为什么这个循环导入*将在python中工作

时间:2017-09-04 07:41:04

标签: python python-import

我在代码中找到了一个奇怪的循环引用,这是最小代码:

ph
|-- mod
|   |-- __init__.py
|   |-- pkg.py  # import mod.sub_mod.sub_pkg
|   `-- sub_mod
|       |-- __init__.py
|       `-- sub_pkg.py  # from mod import pkg
`-- main.py
mod中的

,只有pkg.pysub_pkg.py包含文件内容。

main.py

import mod.pkg

会导致ImportError,但

import mod.sub_mod.sub_pkg

效果很好。

当我试图找到这个最小的可重现的例子时,我发现在python 3中,两个导入都可以工作。 我也找到了这个页面:https://gist.github.com/datagrok/40bf84d5870c41a77dc6但我还是不知道为什么。

1 个答案:

答案 0 :(得分:1)

如果您使用import mod.pkg开始循环导入,则先mod/pkg.py启动,然后尝试import mod.sub_mod.sub_pkgmod/sub_mod/sub_pkg.py启动,并尝试运行from mod import pkg,但mod.pkg模块已初始化。

Python跳过尝试从pkg模块对象中检索mod属性。但是,在mod.pkg模块完成初始化之前,该属性不会设置,因此from mod import pkg会失败。

如果您使用import mod.sub_mod.sub_pkg开始循环导入,则先mod/sub_mod/sub_pkg.py启动,然后尝试运行from mod import pkgmod/pkg.py启动,然后尝试import mod.sub_mod.sub_pkgmod.sub_mod.sub_pkg模块已经初始化,但Python此次没有尝试访问属性。

from mod import pkg需要从pkg检索mod属性,因为它需要将该属性的值绑定到本地命名空间中的名称pkg。但是,import mod.sub_mod.sub_pkg仅绑定本地名称空间中的mod名称。 Python将mod名称绑定到mod模块命名空间中的mod.pkg模块并继续。

在Python 3中,在第一种情况下,当from mod import pkg无法在pkg上找到mod属性时,会出现回退。 Python检查sys.modules dict以查找'mod.pkg'的条目,找到一个,并将找到的模块绑定到pkg名称。