Python 3.7如何用importlib替代imp从字符串动态导入模块?
用importlib替代imp实现字符串动态导入模块
没问题!既然imp模块已经被废弃,用importlib来实现完全可以,而且更符合Python的现代规范。我给你写个完整的替代实现,和原来的imp版本效果完全一致:
import importlib.util def import_code(code, name): # 创建模块规格(spec),因为没有实际文件,loader设为None spec = importlib.util.spec_from_loader(name, loader=None) # 从规格创建空模块对象,这替代了imp.new_module() module = importlib.util.module_from_spec(spec) # 执行代码,将内容注入模块的命名空间 exec(code, module.__dict__) # 可选:为模块添加一些标准属性,让它更像正常导入的模块 module.__file__ = f"<dynamic-module-{name}>" module.__package__ = "" return module # 测试代码和之前一样 code = """ def testFunc(): print('spam!') """ m = import_code(code, 'test') m.testFunc() # 输出: spam!
关键步骤解释:
importlib.util.spec_from_loader():创建模块的规格对象,这里因为我们没有对应的文件加载器,所以把loader设为None,这是动态创建无文件模块的标准方式。importlib.util.module_from_spec():这就是官方推荐替代imp.new_module()的方法,它会根据规格创建一个符合Python模块规范的空对象。exec(code, module.__dict__):和原来的逻辑一样,把代码执行在模块的命名空间里,这样代码里定义的函数、变量都会成为模块的属性。- 可选的属性设置:给模块加上
__file__和__package__是为了让它的行为更接近正常导入的模块,避免某些依赖这些属性的代码报错,你可以根据需求选择是否保留。
这个实现完全兼容Python 3.7+,而且是官方文档推荐的方式,比废弃的imp模块更可靠。
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

