3

可能重复:
Python 中的循环(或循环)导入

一个.py

import b

class Abstract(object):
    pass

class Concrete(Abstract):
    def get_newthing(self):
        return b.NewThing()

(注意:我很难对 a.py 进行任何重大的重构)

b.py

import a
#reload(a)

class NewThing(a.Abstract):
    pass

如所写,运行“import b, a”有效,但运行“import a”给出

AttributeError: 'module' object has no attribute 'Abstract' 

当 Python 到达 a.py 中的“import b”行,然后在导入 b 时尝试访问尚未创建的“a.Abstract”。

但是,如果我包含 reload 语句,我可以很好地执行“import a”,因为 Python 会跳回 a.py 模块并在继续 b.py 之前创建 Abstract 类。所以它似乎有效(尽管我可能应该在重新加载之前添加一个 hasattr 检查)。

我一直在寻找解决此导入循环问题的方法,但没有看到任何关于这些方面的建议。以这种方式使用 reload() 有什么陷阱吗?

4

2 回答 2

0

你的a.py模块设计很糟糕。它迫使您进行循环导入,这通常是要避免的。最好的解决方案是将Concrete类(及其所需的import b行)拆分为一个单独的模块,该模块可以同时导入a并且b没有任何循环。

但是,如果这对您的情况来说重构太多,您可以尝试将import b行从顶部移动a.pyAbstract. 这将解决您遇到的错误,因为它确保NewThing始终能够看到Abstract的定义。

也就是说,执行:

class Abstract(object):
    pass

import b

class Concrete(Abstract):
    def get_newthing(self):
        return b.NewThing()

这是一个最小的更改,但它应该适用于这种情况。但是,如果Concrete需要在定义时访问NewThing该类,则无法以这种方式进行修复。

于 2012-12-15T02:39:37.800 回答
0

不要reload用于此,它仅用于交互式提示。您可以像这样修复这种循环:

class Abstract(object):
    pass

class Concrete(Abstract):
    def get_newthing(self):
        import b
        return b.NewThing()

更好的是重构你的代码,这样你就不需要循环导入。

于 2012-12-15T02:22:15.180 回答