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

Posted

技术标签:

【中文标题】如何替换已弃用的 imp.load_dynamic 的用法?【英文标题】:How to replace usages of deprecated imp.load_dynamic? 【发布时间】:2020-05-26 06:36:01 【问题描述】:

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)

但是为所有类型的项目复制这段代码(at least once 必须改进)感觉很愚蠢。

importlib 的文档proposes 如下:

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]

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

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

还有哪些替代imp.load_dynamic的选项?

【问题讨论】:

【参考方案1】:

importlib.import_module 怎么样?

它还指出:

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

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

【讨论】:

import_module 正在做一些不同的事情。 load_dynamic的一个重要部分是它绕过了sys.path并且文件是显式给出的,还有其他的不同,所以load_dynamic不能被import_module代替

以上是关于如何替换已弃用的 imp.load_dynamic 的用法?的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止 TinyMCE 用 span 替换已弃用的标签

用 Source.fromGraph 替换已弃用的 Source.actorPublisher - 如何限制?

替换 Java Awt 已弃用的方法

NSDateComponents:如何将已弃用的 NSWeekCalendarUnit 替换为计算周开始日期?

Flyway:如何在不出现“FlywayException:验证失败”的情况下替换已弃用的 SpringJdbcMigration?

在iOS 7中替换已弃用的sizeWithFont: