简体   繁体   English

循环导入 Python

[英]Circular imports Python

I've read this post about circular imports in Python.我读过这篇关于 Python 中循环导入的文章 It describes the following scenario and argues that this raises an error when run:它描述了以下场景,并认为这会在运行时引发错误:

# 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()

But when I run this (Python 3.95), it runs perfectly fine.但是当我运行这个(Python 3.95)时,它运行得非常好。 The post is pretty old and it doesn't specify the Python version it uses.这篇文章很旧,它没有指定它使用的 Python 版本。 Maybe there was some change in latter Pythons that support this?也许支持这一点的后期 Python 有一些变化?

Here's a simplified sequence of events that happen in the code in Python 3:下面是 Python 3 代码中发生的简化事件序列:

  1. __init__.py starts running __init__.py开始运行
  2. import module1 starts loading module1.py import module1 module1.py开始加载module1.py
    • An empty module1 module is added to sys.modules一个空的module1模块被添加到sys.modules
  3. import module2 starts loading module2.py import module2开始加载module2.py
    • An empty module2 module is added to sys.modules一个空的module2模块被添加到sys.modules
  4. module2.function2 is created and added tomodule2.__dict__ module2.function2被创建并添加到module2.__dict__
    • The fact that function2 references names in module1 does not affect the creation of the function object in any way function2引用module1中的名称这一事实不会以任何方式影响函数对象的创建
  5. module2 is fully loaded and execution returns to module1 module2被完全加载并且执行返回到module1
  6. module1.function1 and module1.function3 are created and added to module1.__dict__ module1.function1module1.function3被创建并添加到module1.__dict__
    • Again, it does not matter what names the functions reference because they are not being called.同样,函数引用的名称无关紧要,因为它们没有被调用。 AttributeError and NameError can be raised at runtime if necessary.如果需要,可以在运行时引发AttributeErrorNameError
  7. module1 is fully loaded and execution returns to __main__ module1被完全加载并且执行返回到__main__
  8. module1.function runs successfully, since all the names it references are resolvable. module1.function运行成功,因为它引用的所有名称都是可解析的。

As you can see, there are no circular import issues in this particular sequence of imports because module1 and module2 do not attempt to call each other's functions.如您所见,在这个特定的导入序列中没有循环导入问题,因为module1module2不会尝试调用彼此的函数。 The current import system allows both modules to load before the functions are called.当前的导入系统允许在调用函数之前加载两个模块。

The post you mention is from 2017, and must be using a version of python from before 3.0.您提到的帖子是 2017 年的,并且必须使用 3.0 之前的 python 版本。 A hint is found in the link in the following quote, which links to the python-2.x docs:在以下引用中的链接中找到了一个提示,它链接到 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)".这种方法与 Python 语法并不矛盾,正如Python 文档所说:“习惯上但不需要将所有导入语句放在模块(或脚本,就此而言)的开头”。

The paragraph after that is a bit misleading by the way:顺便说一下,后面的段落有点误导:

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 . Python 文档还说,建议使用import X ,而不是其他语句,例如from module import *from module import a,b,c

While star imports are certainly discouraged, specific-name imports of the form from module import a,b,c are generally very much encouraged with few exceptions.虽然肯定不鼓励使用星号导入from module import a,b,c但通常非常鼓励from module import a,b,c形式的特定名称导入,但很少有例外。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM