为什么这个循环导入*将*在 python 中工作
why this circular import *will* work in python
我在我的代码中发现了一个奇怪的循环引用,这里是最小代码:
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.py
和sub_pkg.py
有文件内容。
在main.py
中:
import mod.pkg
会导致ImportError
,但是
import mod.sub_mod.sub_pkg
效果不错。
当我试图找到这个最小的可重现示例时,我发现在 python 3 中,两个导入都可以工作。
我也找到了这个页面:https://gist.github.com/datagrok/40bf84d5870c41a77dc6 但我仍然不知道为什么。
如果您使用 import mod.pkg
开始循环导入,那么 mod/pkg.py
首先开始,然后尝试 import mod.sub_mod.sub_pkg
。 mod/sub_mod/sub_pkg.py
启动,并尝试 运行 from mod import pkg
,但是 mod.pkg
模块已经被初始化。
Python 跳到尝试从 mod
模块对象检索 pkg
属性。但是,直到 mod.pkg
模块完成初始化才设置该属性,因此 from mod import pkg
失败。
如果您使用 import mod.sub_mod.sub_pkg
启动循环导入,则 mod/sub_mod/sub_pkg.py
首先启动,然后尝试 运行 from mod import pkg
。 mod/pkg.py
开始,并尝试 import mod.sub_mod.sub_pkg
。 mod.sub_mod.sub_pkg
模块已经初始化,但是 Python 这次没有尝试访问属性。
from mod import pkg
需要从 mod
检索 pkg
属性,因为它需要将该属性的值绑定到本地命名空间中的名称 pkg
。但是,import mod.sub_mod.sub_pkg
仅绑定本地名称空间中的 mod
名称。 Python 将 mod
名称绑定到 mod.pkg
模块命名空间中的 mod
模块并继续。
在Python 3中,在第一种情况下,当from mod import pkg
在mod
上找不到pkg
属性时,有一个回退。 Python 检查 sys.modules
字典中是否有 'mod.pkg'
的条目,找到一个,并将它找到的模块绑定到 pkg
名称。
我在我的代码中发现了一个奇怪的循环引用,这里是最小代码:
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.py
和sub_pkg.py
有文件内容。
在main.py
中:
import mod.pkg
会导致ImportError
,但是
import mod.sub_mod.sub_pkg
效果不错。
当我试图找到这个最小的可重现示例时,我发现在 python 3 中,两个导入都可以工作。 我也找到了这个页面:https://gist.github.com/datagrok/40bf84d5870c41a77dc6 但我仍然不知道为什么。
如果您使用 import mod.pkg
开始循环导入,那么 mod/pkg.py
首先开始,然后尝试 import mod.sub_mod.sub_pkg
。 mod/sub_mod/sub_pkg.py
启动,并尝试 运行 from mod import pkg
,但是 mod.pkg
模块已经被初始化。
Python 跳到尝试从 mod
模块对象检索 pkg
属性。但是,直到 mod.pkg
模块完成初始化才设置该属性,因此 from mod import pkg
失败。
如果您使用 import mod.sub_mod.sub_pkg
启动循环导入,则 mod/sub_mod/sub_pkg.py
首先启动,然后尝试 运行 from mod import pkg
。 mod/pkg.py
开始,并尝试 import mod.sub_mod.sub_pkg
。 mod.sub_mod.sub_pkg
模块已经初始化,但是 Python 这次没有尝试访问属性。
from mod import pkg
需要从 mod
检索 pkg
属性,因为它需要将该属性的值绑定到本地命名空间中的名称 pkg
。但是,import mod.sub_mod.sub_pkg
仅绑定本地名称空间中的 mod
名称。 Python 将 mod
名称绑定到 mod.pkg
模块命名空间中的 mod
模块并继续。
在Python 3中,在第一种情况下,当from mod import pkg
在mod
上找不到pkg
属性时,有一个回退。 Python 检查 sys.modules
字典中是否有 'mod.pkg'
的条目,找到一个,并将它找到的模块绑定到 pkg
名称。