python - 使用相互或循环(循环)导入时会发生什么?

标签 python python-import circular-dependency cyclic-reference

在 Python 中,当两个模块尝试互相导入时会发生什么?更一般地说,如果多个模块尝试在一个循环中导入会发生什么?

<小时/>

另请参阅 What can I do about "ImportError: Cannot import name X" or "AttributeError: ... (most likely due to a circular import)"?对于可能导致的常见问题,以及有关如何重写代码以避免此类导入的建议。请参阅Why do circular imports seemingly work further up in the call stack but then raise an ImportError further down?了解有关问题发生的原因和方式的技术详细信息。

最佳答案

如果您执行import foo(在bar.py内)和import bar(在foo.py内) ),它会工作得很好。当任何内容实际运行时,两个模块都将完全加载并相互引用。

问题是当您执行 from foo import abc (在 bar.py 内)和 from bar import xyz (在 bar.py 内)时>foo.py)。因为现在每个模块都需要先导入另一个模块(以便我们导入的名称存在)才能导入。

Python 2 和 Python 3 中循环导入的工作示例

文章When are Python circular imports fatal?出于上述原因,给出了循环导入不致命的四个示例。

模块顶部;没有来自;仅限 Python 2

# lib/foo.py                         # lib/bar.py
import bar                           import foo

def abc():                           def xyz():
    print(bar.xyz.__name__)              print(foo.abc.__name__)

模块顶部;从好的;相对还可以;仅限 Python 3

# lib/foo.py                         # lib/bar.py
from . import bar                    from . import foo

def abc():                           def xyz():
    print(bar.xyz.__name__)              print(abc.__name__)

模块顶部;没有来自;无亲属

# lib/foo.py                         # lib/bar.py
import lib.bar                       import lib.foo

def abc():                           def xyz():
    print(lib.bar.xyz.__name__)          print(lib.foo.abc.__name__)

模块底部;导入属性,而不是模块;从好的开始

# lib/foo.py                         # lib/bar.py
def abc():                           def xyz():
    print(xyz.__name__)                  print(abc.__name__)


from .bar import xyz                 from .foo import abc

函数顶部;从好的开始

# lib/foo.py                         # lib/bar.py
def abc():                           def xyz():
    from . import bar                    from . import foo
    print(bar.xyz.__name__)              print(foo.abc.__name__)

其他示例

上面引用的文章没有讨论明星导入。

关于python - 使用相互或循环(循环)导入时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54164400/

相关文章:

python - 如何在 Django 中获取最后 10 项数据?

python - 如何将字符串更改为 QuickFix 消息?

使用 Eclipse PyDev 执行两次 Python 脚本

python-3.x - 在 tensorflow 2 中导入 tensorflow 模块很慢

c++ - 通过两次链接同一个库来解决循环依赖?

c# - DLL 之间的循环依赖

python - 在多个上下文管理器上创建一个 "with" block ?

python - 解压列表/元组中的前两个元素

python - 导入同名方法

c++ - 从它的另一个专业继承的模板可以是循环依赖还是 clang 的错误