Python module dependency

落爺英雄遲暮 提交于 2019-12-02 20:40:38

No need to import CRoom

You don't use CRoom in person.py, so don't import it. Due to dynamic binding, Python doesn't need to "see all class definitions at compile time".

If you actually do use CRoom in person.py, then change from room import CRoom to import room and use module-qualified form room.CRoom. See Effbot's Circular Imports for details.

Sidenote: you probably have an error in Self.NextId += 1 line. It increments NextId of instance, not NextId of class. To increment class's counter use CRoom.NextId += 1 or Self.__class__.NextId += 1.

Do you actually need to reference the classes at class definition time? ie.

 class CRoom(object):
     person = CPerson("a person")

Or (more likely), do you just need to use CPerson in the methods of your class (and vice versa). eg:

class CRoom(object):
    def getPerson(self): return CPerson("someone")

If the second, there's no problem - as by the time the method gets called rather than defined, the module will be imported. Your sole problem is how to refer to it. Likely you're doing something like:

from CRoom import CPerson # or even import *

With circularly referencing modules, you can't do this, as at the point one module imports another, the original modules body won't have finished executing, so the namespace will be incomplete. Instead, use qualified references. ie:

#croom.py
import cperson
class CRoom(object):
    def getPerson(self): return cperson.CPerson("someone")

Here, python doesn't need to lookup the attribute on the namespace until the method actually gets called, by which time both modules should have completed their initialisation.

First, naming your arguments with uppercase letters is confusing. Since Python does not have formal, static type checking, we use the UpperCase to mean a class and lowerCase to mean an argument.

Second, we don't bother with CRoom and CPerson. Upper case is sufficient to indicate it's a class. The letter C isn't used. Room. Person.

Third, we don't usually put things in One Class Per File format. A file is a Python module, and we more often import an entire module with all the classes and functions.

[I'm aware those are habits -- you don't need to break them today, but they do make it hard to read.]

Python doesn't use statically defined types like C++. When you define a method function, you don't formally define the data type of the arguments to that function. You merely list some variable names. Hopefully, the client class will provide arguments of the correct type.

At run time, when you make a method request, then Python has to be sure the object has the method. NOTE. Python doesn't check to see if the object is the right type -- that doesn't matter. It only checks to see if it has the right method.

The loop between room.Room and person.Person is a problem. You don't need to include one when defining the other.

It's safest to import the entire module.

Here's room.py

import person
class Room( object ):
    def __init__( self ):
        self.nextId= 0
        self.people= {}
    def addPerson(self, firstName, secondName, gender):
        id= self.NextId
        self.nextId += 1

        thePerson = person.Person(firstName,secondName,gender,id)
        self.people[id] = thePerson
        return thePerson 

Works fine as long as Person is eventually defined in the namespace where this is executing. Person does not have to be known when you define the class.

Person does not have to be known until runtime when then Person(...) expression is evaluated.

Here's person.py

import room
class Person( object ):
    def something( self, x, y ):
        aRoom= room.Room( )
        aRoom.addPerson( self.firstName, self.lastName, self.gender )

Your main.py looks like this

import room
import person
r = room.Room( ... )
r.addPerson( "some", "name", "M" )
print r

You could just alias the second one.

import CRoom

CPerson = CRoom.CPerson

@S.Lott if i don't import anything into the room module I get an undefined error instead (I imported it into the main module like you showed)

Traceback (most recent call last):
File "C:\Projects\python\test\main.py", line 6, in
Ben = Room.AddPerson('Ben', 'Blacker', 'Male')
File "C:\Projects\python\test\room.py", line 12, in AddPerson
Person = CPerson(FirstName,SecondName,Gender,Id)
NameError: global name 'CPerson' is not defined

Also, the reason there diffrent modules is where I encountered the problem to start with the container class (ieg the room) is already several hundred lines, so I wanted the items in it (eg the people) in a seperate file.

EDIT: main.py

from room import CRoom
from person import CPerson

Room = CRoom()

Ben = Room.AddPerson('Ben', 'Blacker', 'Male')
Tom = Room.AddPerson('Tom', 'Smith',   'Male')

Ben.Leave()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!