为什么周期性进口问题消失了?

Why has the cyclical import issue disappeared?

导入这个包时出现明显的循环导入错误:

文件__init__.py:

from . import modules

文件forward.py:

from .modules import ext_modules

def forward(dest):
    if dest in ext_modules:
        print("forwarding to {}".format(ext_modules[dest]))

文件modules.py:

from . import forward

ext_modules = {}

def main():
    ext_modules['test'] = 'TEST'
    forward.forward('test')

这个导入问题可以解决,例如通过交换 modules.py 文件中的第 1 行和第 3 行。到目前为止,我想我明白发生了什么。

我真正不明白的是这个。当我将另一个导入添加到 __init__.py 文件的顶部时:

from . import forward
from . import modules

问题解决了。包可以导入,主要功能正常。但是 modulesforward 之间的循环依赖仍然存在。这些文件保持不变。你能解释一下那里发生了什么吗? (Python 版本 3.5)

导入模块时发生的第一件事是, module 对象被添加到sys.modules 映射中。同一模块的后续 import 语句将重新使用该对象,而不是将文件加载到内存中。

Python 然后继续执行模块内容并将生成的全局名称添加到那个 module 对象。

对于您的情况,导入模块的顺序很重要。 forward直接依赖modules模块内容,而modules只依赖forward模块存在,不依赖内容该模块的(forward.forward 引用依赖被推迟到 main() 被调用)。

所以如果先导入forward,就会创建空的forward module对象,执行第一行from .modules import ext_modules,触发modules.py 文件,然后可以 安全地 使用 from . import forward 因为 empty module 对象现在存在。 modules.py 文件的其余部分可以继续 运行 而不会发生进一步的事件。

但是如果你首先导入modules,那么还没有forward module对象,所以forward.py文件是运行第二个,并且 from .modules import ext_modules 行失败,因为 modules module 对象仍然是空的并且没有 ext_modules 属性。