a.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语句,我可以“导入”就好了,因为Python跳转到a.py模块并在继续b.py之前创建Abstract类。所以它似乎工作(虽然我应该在重新加载之前添加一个hasattr检查)。
我一直在寻找解决此导入循环问题的方法,并且没有看到任何建议。以这种方式使用reload()是否有任何陷阱?
答案 0 :(得分:0)
此处不要使用reload
,它仅用于交互式提示。您可以像这样修复此循环:
class Abstract(object):
pass
class Concrete(Abstract):
def get_newthing(self):
import b
return b.NewThing()
更好的方法是重构代码,这样就不需要循环导入了。
答案 1 :(得分:0)
a.py
模块的设计非常糟糕。它会强制您进行循环导入,这通常是需要避免的。最好的解决方案是将Concrete
类(以及它所需的import b
行)拆分为一个单独的模块,该模块可以导入a
和b
,而不需要任何循环
但是,如果对您的情况进行过多的重构,您可以尝试将import b
行从a.py
的顶部移动到低于Abstract
定义的点。这样可以解决您遇到的错误,因为它可以确保NewThing
始终能够看到Abstract
的定义。
即,做:
class Abstract(object):
pass
import b
class Concrete(Abstract):
def get_newthing(self):
return b.NewThing()
这是一个微小的变化,但它应该适用于这种情况。如果Concrete
需要对NewThing
类进行定义时访问,则无法通过这种方式进行修复。