为什么带有 import_module 的代码片段会失败?
Why does this snippet with import_module fail?
以下代码创建了一个 Python 包 a.b.c
,然后尝试导入它。它失败了,但是如果我在 try/except!
中注释掉 import_module('a.b')
行,它就可以正常工作
import os.path
from importlib import import_module
import os
import shutil
import sys
shutil.rmtree('a', ignore_errors=True)
os.makedirs('a')
with open('a/__init__.py', 'w'):
pass
try:
# it works if i comment out the following line!
import_module('a.b')
pass
except ImportError:
pass
print(sys.modules.get('a'))
os.makedirs('a/b/c')
with open('a/b/__init__.py', "w"):
pass
with open('a/b/c/__init__.py', "w"):
pass
import_module('a.b.c')
print('ok')
当我 运行 它在我的 Mac(官方 Python 3.6 安装)上时,我得到:
<module 'a' from '/Users/chris1/Documents/a/__init__.py'>
Traceback (most recent call last):
File "/Users/chris1/Documents/foo3.py", line 35, in <module>
import_module('a.b.c')
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 978, in _gcd_import
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 936, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 978, in _gcd_import
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 948, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'a.b'
这个问题只发生在我的 Mac,而不是我的 Windows Python 3.6.
似乎在 Mac 上,import_module
正在将 a
添加到 sys.modules
;我认为这可能与后来导入失败的原因有关。
importlib
似乎缓存了您导入 a.b
失败的结果。当您尝试导入 a.b.c
时,它已经认为 a.b
不存在,即使您创建了它。在尝试再次导入之前,您必须从 importlib
包中调用 invalidate_caches()
。
参考:https://docs.python.org/3/library/importlib.html#importlib.import_module
If you are dynamically importing a module that was created since the
interpreter began execution (e.g., created a Python source file), you
may need to call invalidate_caches()
in order for the new module to be
noticed by the import system.
以下代码创建了一个 Python 包 a.b.c
,然后尝试导入它。它失败了,但是如果我在 try/except!
import_module('a.b')
行,它就可以正常工作
import os.path
from importlib import import_module
import os
import shutil
import sys
shutil.rmtree('a', ignore_errors=True)
os.makedirs('a')
with open('a/__init__.py', 'w'):
pass
try:
# it works if i comment out the following line!
import_module('a.b')
pass
except ImportError:
pass
print(sys.modules.get('a'))
os.makedirs('a/b/c')
with open('a/b/__init__.py', "w"):
pass
with open('a/b/c/__init__.py', "w"):
pass
import_module('a.b.c')
print('ok')
当我 运行 它在我的 Mac(官方 Python 3.6 安装)上时,我得到:
<module 'a' from '/Users/chris1/Documents/a/__init__.py'>
Traceback (most recent call last):
File "/Users/chris1/Documents/foo3.py", line 35, in <module>
import_module('a.b.c')
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 978, in _gcd_import
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 936, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 978, in _gcd_import
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 948, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'a.b'
这个问题只发生在我的 Mac,而不是我的 Windows Python 3.6.
似乎在 Mac 上,import_module
正在将 a
添加到 sys.modules
;我认为这可能与后来导入失败的原因有关。
importlib
似乎缓存了您导入 a.b
失败的结果。当您尝试导入 a.b.c
时,它已经认为 a.b
不存在,即使您创建了它。在尝试再次导入之前,您必须从 importlib
包中调用 invalidate_caches()
。
参考:https://docs.python.org/3/library/importlib.html#importlib.import_module
If you are dynamically importing a module that was created since the interpreter began execution (e.g., created a Python source file), you may need to call
invalidate_caches()
in order for the new module to be noticed by the import system.