代码之家  ›  专栏  ›  技术社区  ›  Fire Lancer

Python模块依赖关系

  •  16
  • Fire Lancer  · 技术社区  · 16 年前

    比如说,我有一个房间模块和一个包含CRoom和CPerson的person模块。

    CRoom类包含关于房间的信息,以及房间中每个人的CPerson列表。

    问题在于两个模块相互导入时,我刚刚收到一个导入错误,第二次导入时会出现该错误:(

    在C++中,我可以只通过包含标题来解决这个问题,因为在这两种情况下,类都有指针指向另一个类,所以向前声明足以满足标题:

    class CPerson;//forward declare
    class CRoom
    {
        std::set<CPerson*> People;
        ...
    

    在python中,除了将两个类放在同一个模块中或类似的东西之外,还有其他方法可以做到这一点吗?

    编辑:添加了python示例,显示使用上述类时出现的问题

    错误:

    回溯(最近一次呼叫最后一次):
    文件“C:\Projects\python\test\main.py”,第1行,在
    从房间进口克罗姆

    从个人进口
    文件“C:\Projects\python\test\person.py”,第1行,在
    从房间进口克罗姆

    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)
    
    5 回复  |  直到 12 年前
        1
  •  21
  •   Constantin    16 年前

    不需要进口CRoom

    你不用 CRoom 在里面 person.py

    如果你真的 使用 克罗姆 在里面 from room import CRoom import room 并使用模块限定形式 room.CRoom Effbot's Circular Imports 详情请参阅。

    旁注: 你可能有一个错误 Self.NextId += 1 线它增加了 NextId 当然不是 当然可以。增加类的计数器使用 CRoom.NextId += 1 Self.__class__.NextId += 1

        2
  •  7
  •   Brian    16 年前

     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不需要查找名称空间上的属性,直到方法实际被调用,这时两个模块都应该完成了初始化。

        3
  •  3
  •   S.Lott    16 年前

    UpperCase 指班级和 lowerCase 指的是争论。

    Room . Person .

    每个文件一个类

    Python不使用静态定义的类型,如C++。定义方法函数时,不会正式定义该函数参数的数据类型。您只需列出一些变量名。希望客户机类能够提供正确类型的参数。

    在运行时,当您发出方法请求时,Python必须确保对象具有该方法。笔记Python不会检查对象的类型是否正确——这无关紧要。它只检查是否有正确的方法。

    之间的循环 room.Room person.Person 这是个问题。定义另一个时,不需要包含其中一个。

    这是 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 
    

    只要Person最终在执行它的命名空间中定义,它就可以正常工作。定义类时,不必知道Person。

    这是 person.py

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

    你的 main.py 看起来像这样

    import room
    import person
    r = room.Room( ... )
    r.addPerson( "some", "name", "M" )
    print r
    
        4
  •  1
  •   Pang Ajmal PraveeN    7 年前

    你可以给第二个别名。

    import CRoom
    
    CPerson = CRoom.CPerson
    
        5
  •  0
  •   Fire Lancer    16 年前

    @洛特 如果我没有将任何内容导入到room模块中,则会得到一个未定义的错误(我将其导入到主模块中,如您所示)

    回溯(最近一次呼叫最后一次):
    文件“C:\Projects\python\test\main.py”,第6行,在

    文件“C:\Projects\python\test\room.py”,第12行,AddPerson
    Person=CPerson(名字、第二个名字、性别、身份证)
    NameError:未定义全局名称“CPerson”

    另外,存在不同模块的原因是我在开始使用容器类(ieg the room)时遇到的问题已经有几百行了,所以我希望其中的项目(例如人员)在一个单独的文件中。

    编辑: 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()