我的团队正在与Django合作开展大型项目。为简单起见,这里用普通的Python来说明问题(原始问题有模型和应用程序而不是类(我知道两者都是类)和包(我知道两者都是包))。
a.py :
from b import B1
class A1(object):
def __init__(self):
print "object A1"
class A2(object):
def __init__(self):
print "object A2"
A1()
B1()
b.py :
from a import A2
class B1(object):
def __init__(self):
print "object B1"
A2()
当调用 a.py 时,它会尝试从 b 包导入 B1 ,另一方面,尝试导入 b 来自 a 包的em> A2 然后,从开始,它将永远重复。 Python说:
[dagrevis@localhost recursion]$ python2 a.py
Traceback (most recent call last):
File "a.py", line 1, in <module>
from b import B1
File "/home/dagrevis/Python/recursion/b.py", line 1, in <module>
from a import A2
File "/home/dagrevis/Python/recursion/a.py", line 1, in <module>
from b import B1
ImportError: cannot import name B1
其中一个解决方案是每个对象有一个文件。像C ++或Java这样的东西。然后我想起了Guido关于Python的内容:“不要在Python中编写Java(或C ++,或Javascript,...)。”是否有更多的Pythonic方法来处理这个问题?
感谢任何建议!
答案 0 :(得分:4)
您的用例不是“可解决的”。您可以将ImportError
转换为AttributeError
导入模块a
(和b
),而不是导入对象,但这并不会改变您无法使用的事实使用这些模块。
问题是您的模块a
要求在导入之前完全执行b
,而b
请求a
要在导入之前完全执行。
这根本不可能解决,这是一个明确的症状,需要重构:您的a
和b
模块应该是一个单独的模块(或者您可能想要进行更深层次的重构)
编辑: 实际上你可以解决这个问题,即使我认为这样做很难看,在需要的时候将导入放在文件的末尾。 但我认为这只是一个更大问题的补丁。
答案 1 :(得分:1)
您的示例过于简化 - 它无法解释为什么需要进行周期性导入。但无论如何,这是将其重构为可运行代码的一种方法:
a.py:
class A1(object):
def __init__(self):
print "object A1"
class A2(object):
def __init__(self):
print "object A2"
b.py:
class B1(object):
def __init__(self):
print "object B1"
c.py:
from a import A1, A2
from b import B1
A1()
A2()
B1()