循环导入 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 中代码中发生的事件的简化序列:

  1. __init__.py 开始 运行
  2. import module1 开始加载 module1.py
    • 一个空的 module1 模块被添加到 sys.modules
  3. import module2 开始加载 module2.py
    • 一个空的 module2 模块被添加到 sys.modules
  4. module2.function2 已创建并添加到 module2.__dict__
    • function2 引用 module1 中的名称这一事实不会以任何方式影响函数对象的创建
  5. module2 已完全加载并执行 returns 到 module1
  6. module1.function1module1.function3 已创建并添加到 module1.__dict__
    • 同样,函数引用什么名称并不重要,因为它们没有被调用。 AttributeErrorNameError 如有必要,可以在运行时引发。
  7. module1 已完全加载并执行 returns 到 __main__
  8. module1.function 运行成功,因为它引用的所有名称都是可解析的。

如您所见,在这个特定的导入序列中没有循环导入问题,因为 module1module2 不会尝试调用彼此的函数。当前的导入系统允许在调用函数之前加载两个模块。

你说的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 形式的特定名称导入,只有少数例外。