导入任意python源文件。(Python 3.3+)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19009932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Import arbitrary python source file. (Python 3.3+)
提问by falsetru
How can I import an arbitrary python source file (whose filename could contain any characters, and does not always ends with .py
) in Python 3.3+?
如何.py
在Python 3.3+ 中导入任意 Python 源文件(其文件名可以包含任何字符,并且并不总是以 结尾)?
I used imp.load_module
as follows:
我使用imp.load_module
如下:
>>> import imp
>>> path = '/tmp/a-b.txt'
>>> with open(path, 'U') as f:
... mod = imp.load_module('a_b', f, path, ('.py', 'U', imp.PY_SOURCE))
...
>>> mod
<module 'a_b' from '/tmp/a-b.txt'>
It still works in Python 3.3, but according to imp.load_module
documentation, it is deprecated:
它仍然适用于 Python 3.3,但根据imp.load_module
文档,它已被弃用:
Deprecated since version 3.3: Unneeded as loaders should be used to load modules and find_module() is deprecated.
3.3 版后已弃用:不需要,因为加载器应该用于加载模块,并且不推荐使用 find_module()。
and imp
module documentation recommends to use importlib
:
和imp
模块文档建议使用importlib
:
NoteNew programs should use importlib rather than this module.
注意新程序应该使用 importlib 而不是这个模块。
What is the proper way to load an arbitrary python source file in Python 3.3+ without using the deprecated imp.load_module
function?
在不使用弃用imp.load_module
函数的情况下,在 Python 3.3+ 中加载任意 Python 源文件的正确方法是什么?
采纳答案by falsetru
Found a solution from importlib
test code.
从importlib
测试代码中找到了解决方案。
Using importlib.machinery.SourceFileLoader:
使用importlib.machinery.SourceFileLoader:
>>> import importlib.machinery
>>> loader = importlib.machinery.SourceFileLoader('a_b', '/tmp/a-b.txt')
>>> mod = loader.load_module()
>>> mod
<module 'a_b' from '/tmp/a-b.txt'>
NOTE: only works in Python 3.3+.
注意:仅适用于Python 3.3+。
UPDATELoader.load_module
is deprecated since Python 3.4. Use Loader.exec_module
instead:
Loader.load_module
自 Python 3.4 起不推荐使用UPDATE。使用Loader.exec_module
来代替:
>>> import types
>>> import importlib.machinery
>>> loader = importlib.machinery.SourceFileLoader('a_b', '/tmp/a-b.txt')
>>> mod = types.ModuleType(loader.name)
>>> loader.exec_module(mod)
>>> mod
<module 'a_b'>
>>> import importlib.machinery
>>> import importlib.util
>>> loader = importlib.machinery.SourceFileLoader('a_b', '/tmp/a-b.txt')
>>> spec = importlib.util.spec_from_loader(loader.name, loader)
>>> mod = importlib.util.module_from_spec(spec)
>>> loader.exec_module(mod)
>>> mod
<module 'a_b' from '/tmp/a-b.txt'>
回答by Stefan Scherfke
Shorter version of @falsetru 's solution:
@falsetru 解决方案的较短版本:
>>> import importlib.util
>>> spec = importlib.util.spec_from_file_location('a_b', '/tmp/a-b.py')
>>> mod = importlib.util.module_from_spec(spec)
>>> spec.loader.exec_module(mod)
>>> mod
<module 'a_b' from '/tmp/a-b.txt'>
I tested it with Python 3.5 and 3.6.
我用 Python 3.5 和 3.6 对其进行了测试。
According to the comments, it does not work with arbitrary file extensions.
根据评论,它不适用于任意文件扩展名。
回答by Alex Walczak
Similar to @falsetru but for Python 3.5+and accounting for what the importlib
docstates on using importlib.util.module_from_spec
over types.ModuleType
:
类似@falsetru但对于Python的3.5+和占什么样的importlib
文档使用状态importlib.util.module_from_spec
了types.ModuleType
:
This function [
importlib.util.module_from_spec
] is preferred over usingtypes.ModuleType
to create a new module as spec is used to set as many import-controlled attributes on the module as possible.
此函数 [
importlib.util.module_from_spec
] 优于types.ModuleType
用于创建新模块,因为规范用于在模块上设置尽可能多的导入控制属性。
We are able to import any file with importlib
alone by modifying the importlib.machinery.SOURCE_SUFFIXES
list.
我们可以importlib
通过修改importlib.machinery.SOURCE_SUFFIXES
列表单独导入任何文件。
import importlib
importlib.machinery.SOURCE_SUFFIXES.append('') # empty string to allow any file
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
# if desired: importlib.machinery.SOURCE_SUFFIXES.pop()