python import_module行为不一致

时间:2019-01-30 19:22:25

标签: python-3.x python-importlib

我遇到了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调用,该调用也被证明是“有效的”,因为这不是时间敏感的过程。还有其他想法吗?我可以接受这种破解,但对我来说却很奇怪!

0 个答案:

没有答案