python - 尝试两次导入损坏的包时出现错误的 ImportError

标签 python python-3.x

我在两次尝试导入损坏的包时注意到了奇怪的行为。让我们考虑以下包:

| package
|--| __init__.py
|--| module1.py

其中 module1.py 为空且 __init__.py 包含:

from package import module1
from package import module2

第一次尝试导入package时,会引发ImportError,因为缺少module2:

>>> import package
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/tmp/package/__init__.py", line 2, in <module>
    from package import module2
ImportError: cannot import name 'module2'

但在第二次尝试时,ImportError 提示 module1:

>>> import package
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/tmp/package/__init__.py", line 1, in <module>
    from package import module1
ImportError: cannot import name 'module1'

即使 module1 之前已成功导入。它甚至可以在 sys.modules 中使用:

>>> import sys
>>> sys.modules["package.module1"]
<module 'package.module1' from '/tmp/package/module1.py'>

但是,这似乎在 Python 3.5 中得到了修复,可能是因为 circular imports involving relative imports are now supported .

到底发生了什么?

最佳答案

第一次导入package.module1,从那时起就存在于sys.modules中。但是,由于 package.module2 上的导入错误,package 本身的导入没有成功,因此 package 没有结束在sys.modules中。

第二次尝试导入package将以不同的方式处理package.module1的导入,因为它已经存在于sys.modules中。这次的代码路径假设在某个时刻,如果 sys.modules 中存在带有点名称的模块,则所有父级也会这样做。然而,在第一次尝试导入package失败后,这一假设就不再成立。

简而言之,导入一个包可能会导致导入更多的包和模块,这对于填充 sys.modules 来说不是原子的,而 Python 3.4 之前做了一些假设,需要原子性。

关于python - 尝试两次导入损坏的包时出现错误的 ImportError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35506691/

相关文章:

python - 使用 Conda Build 时导入测试失败

python - djangorest框架——如果身份验证失败,则使用下一个参数重定向到登录

python - 如何计算两个包含 Python 字符串的列表的 Jaccard 相似度?

python - 通过 Youtube 上传,通过 api 设置为私有(private)(锁定)

Python dev_appserver 无法导入 `.so` 文件(枕头)

python - sys_platform 未定义 x64 Windows

python - 在 Python 3.6 中使用 "or"或 "or-like"语句

python - 沿一个轴组合附近的边界框

python - 通过 Python 脚本 : trouble with component, duedate 和 fixversion 字段创建 Jira 问题已编辑

python-3.x - 使用变量定义的 f 字符串