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

Python: Importing arbitrarily named source files using importlib

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

1
2
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: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses

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

1
2
3
4
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)

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

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

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

(这样,通过my_module['name']而不是my_module.name可以使用my_module中定义的名称,但是您知道了)。我想知道使用importlib

的正确方法


一个类似问题的解决方案在这里发布。翻译成我的示例:

1
2
3
4
5
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)