【问题标题】:Access class from a file imported by the class definition file从类定义文件导入的文件中访问类
【发布时间】:2014-10-10 04:41:35
【问题描述】:

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

文件 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 的最后一行失败:type object 'A' hast no attribute 'instance'。如果 A 和 B 在同一个文件中,它可以工作。如何将其拆分为多个文件以防止将整个项目放在一个巨大的文件中?

【问题讨论】:

  • 直到你运行A.__init__A.instance 是未定义的。你到底想达到什么目的?!
  • @jonrsharpe:A.__init__ 正在运行,因为他执行a = A()。但不是正确的A,因为模块被导入了两次。

标签: python python-2.7


【解决方案1】:

当您运行A.py 时,它被认为具有名称__main__(在您的if __name__ == '__main__' 测试中使用)。但是当 B 导入 A 时,它的名称为 A。因此,该模块以不同的名称加载了两次,并且存在两个副本。当您的“主”块运行时,它正在从__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()

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

【讨论】:

  • 我收到“全局名称 'A' 未在文件 B 中定义。”
  • @Toast:你在 A 和 B 有什么?您仍然需要两个文件中的导入。
  • @Toast:正如我所说,您需要 两个文件中的导入。你仍然需要在 B.py 中使用 from A import *(或 from A import A),就像你一开始一样。
  • 我再次更新了问题。在第 1 行的 B 中导入时失败:“ImportError:无法导入名称 A”,或带有星号:“未定义全局名称 'A'”
  • @Toast:哦,哎呀,忘了那个并发症。您将需要更改导入的形式。请参阅我编辑的答案。
猜你喜欢
  • 1970-01-01
  • 2016-12-26
  • 2023-01-04
  • 2020-07-25
  • 2016-12-14
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多