共计 2726 个字符,预计需要花费 7 分钟才能阅读完成。
最近在对 zabbix 依赖的接口主动探测脚本做配置化改造,脚本里面用到了 importlib 提供的动态 import 功能,由于这一次一时性起全程 vim 操作没有用 pycharm,vim 一时爽,一直用一直爽,雾~ 等会我会说到不用 pycharm 导致的问题。
下面我用一个 demo 来复现一下问题,也便于大家理解,以下是目录结构和代码内容:
$ tree
├── demo
│ ├── cc_test.py
├── demo.py
$ cat demo.py
import importlib
path='cc'
lib=importlib.import_module('demo.'+path+'_test')
print(lib.ccc)
$ cat demo/cc_test.py
ccc='111'
你可以按照上面的目录结构和代码内容组织好,然后用 python2 运行一下,大致会报下面的错误,
$ python2 demo.py
Traceback (most recent call last):
File "demo.py", line 3, in <module>
lib=importlib.import_module('demo.'+path+'_test')
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "/Users/sharp/Downloads/demo.py", line 3, in <module>
lib=importlib.import_module('demo.'+path+'_test')
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
ImportError: No module named cc_test
总之会直接报没有叫 cc_test 的模块的错误,这样子就很迷惑了,你左看右看 demo 目录下都有一个叫 cc_test.py 的模块,怎么会没有呢,而当你不小心用 python3 来运行的时候会发现有的系统的源安装的 python3 可能什么错都不会报,正常输出结果,这就更让人迷惑了,当然还有一种输出,就是直接告诉你 demo 这个目录不是一个包,这时即使是 python 初学者也会知道给这个包加一个__init__.py 的文件就可以解决问题了,如下:
$ python3 demo.py
Traceback (most recent call last):
File "demo.py", line 3, in <module>
lib=importlib.import_module('demo.'+path+'_test')
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/Users/sharp/Downloads/demo.py", line 3, in <module>
lib=importlib.import_module('demo.'+path+'_test')
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 962, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'demo.cc_test'; 'demo' is not a package
可是博主就非常不幸了,遇到了第一种情况,本地开发环境的 python3 什么错都不报,我也是折腾了个把小时才发现了问题,所以回到开始,我只想说 pycharm 大法好!因为 pycharm 新建包的时候会自动创建__init__.py。
正文完
发表至: Python编程
2021-03-16