好的我有两个模块,每个模块都包含一个类,问题是它们的类互相引用.
让我们说例如我有一个房间模块和一个包含CRoom和CPerson的人员模块.
CRoom类包含有关房间的信息,以及房间中每个人的CPerson列表.
然而,CPerson类有时需要将CRoom类用于它的房间,例如找到门,或者看看房间里还有谁.
问题是两个模块互相导入我只是得到一个导入错误,其中第二次导入:(
在c ++中,我可以通过仅包含头来解决这个问题,因为在这两种情况下类都只有指向另一个类的指针,前向声明就足以满足标题,例如:
class CPerson;//forward declare class CRoom { std::setPeople; ...
反正有没有在python中执行此操作,除了将两个类放在同一个模块或类似的东西?
编辑:添加了使用上面的类显示问题的python示例
错误:
回溯(最近一次调用最后一次):
文件"C:\ Projects\python\test\main.py",第1行,
从房间导入CRoom
文件"C:\ Projects\python\test\room.py",第1行,
来自人员导入CPerson
文件"C:\ Projects\python\test\person.py",第1行,
从房间导入 CRoom
ImportError:无法导入名称
CRoom room.py
from person import CPerson class CRoom: def __init__(Self): Self.People = {} Self.NextId = 0 def AddPerson(Self, FirstName, SecondName, Gender): Id = Self.NextId Self.NextId += 1# Person = CPerson(FirstName,SecondName,Gender,Id) Self.People[Id] = Person return Person def FindDoorAndLeave(Self, PersonId): del Self.People[PeopleId]
person.py
from room import CRoom class CPerson: def __init__(Self, Room, FirstName, SecondName, Gender, Id): Self.Room = Room Self.FirstName = FirstName Self.SecondName = SecondName Self.Gender = Gender Self.Id = Id def Leave(Self): Self.Room.FindDoorAndLeave(Self.Id)
Constantin.. 20
无需导入CRoom
你不使用CRoom
in person.py
,所以不要导入它.由于动态绑定,Python不需要"在编译时查看所有类定义".
如果你确实不使用CRoom
的person.py
,然后换from room import CRoom
到import room
和使用模块合格形式room.CRoom
.有关详细信息,请参阅Effbot的循环导入.
旁注:你可能有一个错误Self.NextId += 1
.它增加NextId
了实例,而不是NextId
类.增加班级的反击使用CRoom.NextId += 1
或Self.__class__.NextId += 1
.
无需导入CRoom
你不使用CRoom
in person.py
,所以不要导入它.由于动态绑定,Python不需要"在编译时查看所有类定义".
如果你确实不使用CRoom
的person.py
,然后换from room import CRoom
到import room
和使用模块合格形式room.CRoom
.有关详细信息,请参阅Effbot的循环导入.
旁注:你可能有一个错误Self.NextId += 1
.它增加NextId
了实例,而不是NextId
类.增加班级的反击使用CRoom.NextId += 1
或Self.__class__.NextId += 1
.
你真的需要在类定义时引用类吗?即.
class CRoom(object): person = CPerson("a person")
或者(更有可能),你是否只需要在你的类的方法中使用CPerson(反之亦然).例如:
class CRoom(object): def getPerson(self): return CPerson("someone")
如果是第二个,则没有问题 - 因为在调用方法而不是定义方法时,将导入模块.你唯一的问题是如何引用它.可能你正在做的事情如下:
from CRoom import CPerson # or even import *
使用循环引用模块,您无法执行此操作,因为在一个模块导入另一个模块时,原始模块主体将不会执行完毕,因此命名空间将不完整.相反,使用合格的引用.即:
#croom.py import cperson class CRoom(object): def getPerson(self): return cperson.CPerson("someone")
在这里,python不需要在命名空间中查找属性,直到方法实际被调用,这时两个模块都应该完成初始化.