gpt4 book ai didi

使用 from package import module 语法时 Python 循环导入失败

转载 作者:行者123 更新时间:2023-12-01 05:56:34 24 4
gpt4 key购买 nike

Possible Duplicate:
Cyclic module dependencies and relative imports in Python

考虑以下 python 中循环导入的示例:

main.py:

from pkg import foo

pkg/__init.py__:

# empty

pkg/foo.py:

from pkg import bar

pkg/bar.py:

from pkg import foo

运行main.py会引发异常:

Traceback (most recent call last):
File "/path/to/main.py", line 1, in <module>
from pkg import foo
File "/path/to/pkg/foo.py", line 1, in <module>
from pkg import bar
File "/path/to/pkg/bar.py", line 1, in <module>
from pkg import foo
ImportError: cannot import name foo

将 bar.py 更改为:

# from pkg import foo
import pkg.foo

将使示例正常工作。

为什么会发生这种情况? *import package.module"和 "from package import module"不应该是等价的(除了后者中的额外名称绑定(bind))?

最佳答案

首先你必须明白:

  • sys.modules变量在导入机制中扮演缓存的角色,这意味着如果我们第一次导入模块,包含该模块名称的条目将添加到 sys.modules ,这样当我们下次尝试导入同一个模块时,我们只会从 sys.modules 获取已经缓存的模块。我们不会再次执行该模块。

  • import pkg.foo之间的区别和from pkg import foo第二个也是等价的:import pkg.foo接下来是 getattr(pkg, 'foo') 。 (查看我的回答 here 了解更多详情)

现在第一个示例中发生的情况如下:

1- 在 main.py :我们首先执行 from pkg import foo 行,所以首先输入 pkg.foo添加到sys.modules (即 'pkg.foo' in sys.modules == True )比我们尝试导入 foo .

2- 在 foo.py :导入时foo我们最终执行这一行:from pkg import bar再次输入 pkg.bar添加到sys.modules ;然后我们开始导入bar ,这里需要注意的是我们仍在执行 foo.py ,所以我们仍然执行此行 from pkg import foo来自main.py

3- 在 bar.py :正在导入bar.py我们最终执行了这一行:from pkg import foo ,但请记住我们已经在 sys.modules 中有一个条目对于 pkg.foo这意味着执行 foo.py将被跳过,导入机制将为我们提供 sys.modules['pkg.foo']进入,现在我们将执行getattr(pkg, 'foo')如上所述,但请记住“pkg.foo”没有完成导入;这意味着没有属性 foo这解释了错误。

现在如果你输入bar.pyimport pkg.foo这不会有上次导致我们出现问题的行: getattr(pkg, 'foo') .

HTH,

关于使用 from package import module 语法时 Python 循环导入失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12330891/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com