如何替换已弃用的 imp.load_dynamic 的用法?

ead*_*ead 6 python python-3.x python-importlib

该imp模块已被弃用(自版本 3.4 起),但是基础设施的某些部分(例如pyximport)仍然使用imp.load_dynamic,这会导致较新的 Python 版本出现弃用警告。

在内部,imp.load_dynamic使用importlib-machinery:

from importlib._bootstrap import _load
def load_dynamic(name, path, file=None):
    """**DEPRECATED**
    Load an extension module.
    """
    import importlib.machinery
    loader = importlib.machinery.ExtensionFileLoader(name, path)

    # Issue #24748: Skip the sys.modules check in _load_module_shim;
    # always load new extension
    spec = importlib.machinery.ModuleSpec(
        name=name, loader=loader, origin=path)
    return _load(spec)
Run Code Online (Sandbox Code Playgroud)

但为所有类型的项目重复此代码(至少需要改进一次)感觉很愚蠢。

importlib的文档提出以下建议:

import importlib.util
import sys
def alternative_load_dynamic(name, path, file=None):
    spec = importlib.util.spec_from_file_location(name, path)
    module = importlib.util.module_from_spec(spec)
    sys.modules[name] = module
    spec.loader.exec_module(module)
    return sys.modules[name]
Run Code Online (Sandbox Code Playgroud)

虽然与第一个实现(即 )相比,它具有不使用私有 API 的优点,并且获得了问题 #24748_load的核心行为,但它并不是以下内容的直接替代品:imp.load_dynamic

  • 这个替代方案可以更多:它还可以加载纯Python模块(*.py或*.pyc)。
  • 这种替代方案可以减少:它只能加载带有结尾的动态模块*.so(或*.pyd在 Windows 上),但不能加载例如foo.my_ending.

还有哪些其他选项可以替代imp.load_dynamic?

小智 -2

怎么样importlib.import_module?

它还指出:

如果您动态导入自解释器开始执行以来创建的模块(例如,创建Python 源文件),您可能需要调用invalidate_caches() 以便导入系统注意到新模块。

https://docs.python.org/3/library/importlib.html#importlib.import_module