我遇到了Python3的importlib.import_module
函数的某些奇怪且不一致的行为。我想知道1)是否有人曾经历过这种情况,以及2)补救的最佳方法。如果相关,我将在基于Debian(stretch)的Docker容器中使用Python 3.5.3。
背景是我有一个框架,允许开发人员编写少量的自定义代码。作为一个非常基本的检查,我的脚本使用importlib.import_module
来“获取”代码。如果它们的代码存在非常明显的问题,则会引发语法错误等。
我创建一个暂存目录,并将其python文件复制到该文件夹中。然后,我从下面与BASE_DIR
相同的目录中运行:
# if base is /foo, and module_path is at /foo/bar/xyz.py
# this gives bar/xyz.py
module_path_relative_to_base = os.path.relpath(
module_path,
start=BASE_DIR
)
# makes "bar/xyz.py" into "bar.xyz"
module_dot_path = module_path_relative_to_base.replace('/', '.')[:-3]
# import that module:
mod = import_module(module_dot_path)
大多数的时间(例如,80%的时间)有效。但是,有时我会出错:
Traceback (most recent call last):
File "workflow_ingestion/ingest_workflow.py", line 700, in <module>
handler_name_list = check_handlers(staging_dir)
File "workflow_ingestion/ingest_workflow.py", line 495, in check_handlers
inspect_handler_module(module_path, 'add_to_context', 2)
File "workflow_ingestion/ingest_workflow.py", line 432, in inspect_handler_module
mod = import_module(module_dot_path)
File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 956, in _find_and_load_unlocked
ImportError: No module named 'workflow_ingestion.staging.20190130.file_chooser_handler'
似乎表明文件workflow_ingestion/staging/20190130/file_chooser_handler.py
不存在。事实并非如此-当我列出此错误后的目录时,该文件肯定存在。
但是,奇怪的是,如果我在对print
的调用之前放置了importlib.import_module
语句,它总是可以工作的!删除print
调用后,错误再次出现(!!)。
我想知道这是否是一个奇怪的bug(?),其中先前的文件副本(使用python的shutil.copy2
)尚未完全“注册”到文件系统/ OS,或者尚未与python的交互?文件系统/ OS不在我的掌舵之下,所以我不知道这是否可能是源。
我的临时解决方案是保留该打印语句,或添加一个time.sleep
调用,该调用也被证明是“有效的”,因为这不是时间敏感的过程。还有其他想法吗?我可以接受这种破解,但对我来说却很奇怪!