我在尝试两次导入损坏的包时发现了一种奇怪的行为。我们来考虑以下方案:
| 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。
到底发生了什么?
答案 0 :(得分:2)
第一次导入package.module1
,然后导入sys.modules
。但是,由于package.module2
上的导入错误,导致package
本身并未成功,因此,package
不会以sys.modules
结尾。
导入package
的第二次尝试将以package.module1
中已有的方式处理sys.modules
的导入。这次的代码路径在某些时候假设如果sys.modules
中存在带有虚线名称的模块,那么所有父母也会这样做。但是,在首次尝试导入package
失败后,此假设未得到满足。
简而言之,导入一个可能导致更多包和模块被导入的包,对于填充sys.modules
而言并不是原子的,而高达3.4的Python做了一些需要原子性的假设。