循环导入 Python
Circular imports Python
我在 Python 中阅读了 this post 关于循环导入的内容。它描述了以下场景,并认为这会在 运行:
时引发错误
# module1
import module2
def function1():
module2.function2()
def function3():
print('Goodbye, World!')
# module2
import module1
def function2():
print('Hello, World!')
module1.function3()
# __init__.py
import module1
module1.function1()
但是当我 运行 这个 (Python 3.95) 时,它 运行 完全没问题。 post 很旧,它没有指定它使用的 Python 版本。也许在后面的 Python 中有一些支持这个的变化?
这是 Python 3 中代码中发生的事件的简化序列:
__init__.py
开始 运行
- 一个空的
__main__
module is added to sys.modules
import module1
开始加载 module1.py
- 一个空的
module1
模块被添加到 sys.modules
import module2
开始加载 module2.py
- 一个空的
module2
模块被添加到 sys.modules
module2.function2
已创建并添加到 module2.__dict__
function2
引用 module1
中的名称这一事实不会以任何方式影响函数对象的创建
module2
已完全加载并执行 returns 到 module1
module1.function1
和 module1.function3
已创建并添加到 module1.__dict__
- 同样,函数引用什么名称并不重要,因为它们没有被调用。
AttributeError
和 NameError
如有必要,可以在运行时引发。
module1
已完全加载并执行 returns 到 __main__
module1.function
运行成功,因为它引用的所有名称都是可解析的。
如您所见,在这个特定的导入序列中没有循环导入问题,因为 module1
和 module2
不会尝试调用彼此的函数。当前的导入系统允许在调用函数之前加载两个模块。
你说的post是2017年的,肯定是用的python3.0之前的版本。在以下引用的 link 中找到了一个提示,link 指向 python-2.x 文档:
This approach doesn't contradict Python syntax, as the Python documentation says: "It is customary but not required to place all import statements at the beginning of a module (or script, for that matter)".
顺便说一句,后面的段落有点误导:
The Python documentation also says that it is advisable to use import X
, instead of other statements, such as from module import *
, or from module import a,b,c
.
虽然肯定不鼓励明星导入,但通常非常鼓励 from module import a,b,c
形式的特定名称导入,只有少数例外。
我在 Python 中阅读了 this post 关于循环导入的内容。它描述了以下场景,并认为这会在 运行:
时引发错误# module1
import module2
def function1():
module2.function2()
def function3():
print('Goodbye, World!')
# module2
import module1
def function2():
print('Hello, World!')
module1.function3()
# __init__.py
import module1
module1.function1()
但是当我 运行 这个 (Python 3.95) 时,它 运行 完全没问题。 post 很旧,它没有指定它使用的 Python 版本。也许在后面的 Python 中有一些支持这个的变化?
这是 Python 3 中代码中发生的事件的简化序列:
__init__.py
开始 运行- 一个空的
__main__
module is added tosys.modules
- 一个空的
import module1
开始加载module1.py
- 一个空的
module1
模块被添加到sys.modules
- 一个空的
import module2
开始加载module2.py
- 一个空的
module2
模块被添加到sys.modules
- 一个空的
module2.function2
已创建并添加到module2.__dict__
function2
引用module1
中的名称这一事实不会以任何方式影响函数对象的创建
module2
已完全加载并执行 returns 到module1
module1.function1
和module1.function3
已创建并添加到module1.__dict__
- 同样,函数引用什么名称并不重要,因为它们没有被调用。
AttributeError
和NameError
如有必要,可以在运行时引发。
- 同样,函数引用什么名称并不重要,因为它们没有被调用。
module1
已完全加载并执行 returns 到__main__
module1.function
运行成功,因为它引用的所有名称都是可解析的。
如您所见,在这个特定的导入序列中没有循环导入问题,因为 module1
和 module2
不会尝试调用彼此的函数。当前的导入系统允许在调用函数之前加载两个模块。
你说的post是2017年的,肯定是用的python3.0之前的版本。在以下引用的 link 中找到了一个提示,link 指向 python-2.x 文档:
This approach doesn't contradict Python syntax, as the Python documentation says: "It is customary but not required to place all import statements at the beginning of a module (or script, for that matter)".
顺便说一句,后面的段落有点误导:
The Python documentation also says that it is advisable to use
import X
, instead of other statements, such asfrom module import *
, orfrom module import a,b,c
.
虽然肯定不鼓励明星导入,但通常非常鼓励 from module import a,b,c
形式的特定名称导入,只有少数例外。