如何替换已弃用的 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
的直接替代品:
*.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 的用法?的主要内容,如果未能解决你的问题,请参考以下文章
用 Source.fromGraph 替换已弃用的 Source.actorPublisher - 如何限制?
NSDateComponents:如何将已弃用的 NSWeekCalendarUnit 替换为计算周开始日期?
Flyway:如何在不出现“FlywayException:验证失败”的情况下替换已弃用的 SpringJdbcMigration?