从类定义文件导入的文件中访问类

时间:2014-08-16 20:04:43

标签: python python-2.7

这是我的工作代码(简化):

文件A.py:

from B import *

class A(object):
    def __init__(self):
        A.instance = self
        self.b = B()

    def testA(self):
        print "success"

if __name__ == '__main__':
    a = A()
    a.b.testB()

文件B.py:

from A import *

class B(object):
    def testB(self):
        A.instance.testA()

它在B.py的最后一行失败:类型对象' A'没有属性'实例'。如果A和B在同一个文件中,它可以工作。如何将其拆分为多个文件以防止将整个项目放在一个巨大的文件中?

1 个答案:

答案 0 :(得分:1)

当您运行A.py时,会将其视为名称__main__(在您的if __name__ == '__main__'测试中使用)。但是当B导入A时,它的名称为A。因此模块以不同的名称加载两次,并且存在两个副本。当你的“main”块运行时,它会从__main__实例化A类,但是B.py只能看到模块A中的A类。 (有关类似问题,请参阅this recent question;有关双重导入问题的更多说明,请参见this one。)

解决方案是从您要作为脚本运行的文件中分离出需要导入的代码。将类放在单独的文件A.py和B.py中,然后有第三个文件(script.py或其他),它可以完成两个文件所需的任何操作。例如,您的script.py可以执行:

from A import A

if __name__ == "__main__":
    a = A()
    a.b.testB()

然后您可以像这样设置A和B:

### A.py
import B

class A(object):
    def __init__(self):
        A.instance = self
        self.b = B.B()

    def testA(self):
        print "success"

### B.py
import A

class B(object):
    def testB(self):
        A.A.instance.testA()

拥有多个相互导入的模块通常是一个冒险的主张。如果您有多个需要相互引用的类,最简单的方法是将它们保存在同一个模块中。 (如果由于你有大量的相互引用类而变得很尴尬,你可能想要修改你的整体设计,因为大量的相互引用类可能很难。)