我在两次尝试导入损坏的包时注意到了奇怪的行为。让我们考虑以下包:
| 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/