好的,我有两个模块,每个模块都包含一个类,问题是它们的类相互引用。
假设我有一个房间模块和一个包含 CRoom 和 CPerson 的人员模块。
CRoom 类包含有关房间的信息,以及房间中每个人的 CPerson 列表。
但是,CPerson 类有时需要使用 CRoom 类作为其所在的房间,例如寻找门,或者查看房间里还有谁。
问题在于两个模块相互导入,我只是得到一个导入错误,第二个导入的是哪个模块:(
在 c++ 中,我可以通过只包含标题来解决这个问题,因为在这两种情况下,类都只有指向另一个类的指针,所以前向声明就足够了,例如:
class CPerson;//forward declare
class CRoom
{
std::set<CPerson*> People;
...
除了将两个类放在同一个模块或类似的东西中之外,还有什么办法在 python 中做到这一点?
编辑:添加了显示使用上述类的问题的python示例
错误:
Traceback (most recent call last):
File "C:\Projects\python\test\main.py", line 1, in
from room import CRoom
File "C:\Projects\python\test\room.py", line 1, in
from person import CPerson
File "C:\Projects\python\test\person.py", line 1, in
from room import CRoom
ImportError: cannot import name 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)
最佳答案
无需导入CRoom
你没有在 person.py
中使用 CRoom
,所以不要导入它。由于动态绑定(bind),Python 不需要“在编译时查看所有类定义”。
如果你真的做在 person.py
中使用 CRoom
,那么将 from room import CRoom
改为 import room
并使用模块限定形式 room.CRoom
。见 Effbot's Circular Imports了解详情。
旁注:您可能在 Self.NextId += 1
行中有错误。它增加实例的 NextId
,而不是类的 NextId
。要增加类的计数器,请使用 CRoom.NextId += 1
或 Self.__class__.NextId += 1
。
关于Python 模块依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/158268/