可能重复:
Cyclic module dependencies and relative imports in Python
在python中考虑下面的循环导入示例:
main.py:
from pkg import foo
PKG / __ init.py __:
# empty
PKG / foo.py:
from pkg import bar
PKG / bar.py:
from pkg import foo
运行main.py会导致异常:
Traceback (most recent call last):
File "/path/to/main.py", line 1, in <module>
from pkg import foo
File "/path/to/pkg/foo.py", line 1, in <module>
from pkg import bar
File "/path/to/pkg/bar.py", line 1, in <module>
from pkg import foo
ImportError: cannot import name foo
将bar.py更改为:
# from pkg import foo
import pkg.foo
将使示例有效。
为什么会这样?不应该*导入package.module“和”从包导入模块“是等效的(除了后者中的额外名称绑定)?
答案 0 :(得分:2)
首先你必须明白:
sys.modules
变量在导入机制中扮演缓存的角色,这意味着如果我们第一次导入模块,则会将包含此模块名称的条目添加到{{1}因此,当我们下次尝试导入同一个模块时,我们只会从sys.modules
获取已缓存的模块,我们将不再执行该模块。
sys.modules
和import pkg.foo
之间的区别在于第二个也是等效的:from pkg import foo
后跟import pkg.foo
。 (查看我的回答here了解更多详情)
现在你的第一个例子中发生了以下情况:
1-在getattr(pkg, 'foo')
中:我们首先执行第main.py
行,因此首先将条目from pkg import foo
添加到pkg.foo
(即sys.modules
)我们尝试导入'pkg.foo' in sys.modules == True
。
2-在foo
中:导入foo.py
时,我们最终执行此行:foo
并再次将条目from pkg import bar
添加到pkg.bar
;而且我们开始导入sys.modules
,这里需要注意的是我们仍在执行bar
,所以我们仍然可以从foo.py
执行此行from pkg import foo
。
3-在main.py
中:在导入bar.py
时,我们最终会执行以下行:bar.py
,但请记住我们from pkg import foo
中已有sys.modules
的条目这意味着将跳过执行pkg.foo
,导入机制将使我们获得foo.py
条目,现在我们将执行sys.modules['pkg.foo']
,如上所述,但请记住'pkg.foo '没有完成进口;这意味着没有解释错误的属性getattr(pkg, 'foo')
。
现在,如果您只使用foo
bar.py
,那么上次不会出现导致我们问题的行:import pkg.foo
。
HTH,