Python:使用importlib导入任意命名的源文件

时间:2018-07-28 21:10:19

标签: python python-3.x python-importlib python-3.7 imp

给定绝对文件名,我使用imp模块从源代码导入Python模块。即

import imp
my_module = imp.load_source('my_module', '/paht/to/my_module')

在这里,/paht/to/my_module是包含Python源代码的文件的完整路径,即使该文件没有扩展名.py

在Python 3.7中执行import imp时,显示以下弃用警告:

  

DeprecationWarning:不建议使用imp模块,而推荐使用importlib;请参阅该模块的文档以供其他用途

因此,我正在寻找importlib函数的imp.load_source替代品。在docs中,我有以下内容:

import importlib.util
spec = importlib.util.spec_from_file_location('my_module', '/paht/to/my_module')
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

在文件名没有扩展名的情况下,这不起作用,例如我的情况。我猜它失败了,因为没有实现的“查找程序​​”将文件识别为Python源文件。但是,我确实不需要这些查找器提供的所有复杂机制,因为我可以肯定地知道文件的绝对路径。我只是想将其导入。

一个简单的技巧就是将源代码作为文本读入并在其自己的命名空间中手动执行,例如

my_module = {} 
exec(open('/paht/to/my_module').read(), my_module)

(这样,在my_module中定义的名称可以通过my_module['name']而不是my_module.name获得,但是您可以理解。我想知道使用importlib的正确方法。

1 个答案:

答案 0 :(得分:1)

针对类似问题的解决方案已发布here。翻译成我的例子:

import importlib.machinery, importlib.util
loader = importlib.machinery.SourceFileLoader('my_module', '/path/to/my_module')
spec = importlib.util.spec_from_loader(loader.name, loader)
my_module = importlib.util.module_from_spec(spec)
loader.exec_module(my_module)