导入任意python源文件。(Python 3.3+;)
如何在python 3.3+中导入任意python源文件(其文件名可以包含任何字符,并且不总是以导入任意python源文件。(Python 3.3+;),python,python-3.x,python-3.3,Python,Python 3.x,Python 3.3,如何在python 3.3+中导入任意python源文件(其文件名可以包含任何字符,并且不总是以.py结尾) 我使用的方法如下: >>> 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)) ... >>
.py
结尾)
我使用的方法如下:
>>> 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'>
导入imp
>>>路径='/tmp/a-b.txt'
>>>打开(路径“U”)作为f:
... mod=imp.load_模块('a_b',f,path,('.py',U',imp.py_源))
...
>>>国防部
它仍然在Python 3.3中工作,但根据imp.load_module
文档,它已被弃用:
自3.3版以来已弃用:不需要加载程序,因为应使用加载程序
不推荐使用load module and find_module()
和imp
模块文档建议使用importlib
:
注意新程序应使用importlib而不是此模块
在python 3.3+中加载任意python源文件而不使用不推荐的imp.load\u模块
函数的正确方法是什么?从中找到了一个解决方案
使用:
>>进口进口机械
>>>导入importlib.util
>>>loader=importlib.machine.SourceFileLoader('a_b','/tmp/a-b.txt'))
>>>spec=importlib.util.spec_from_loader(loader.name,loader)
>>>mod=importlib.util.module\u from\u spec(spec)
>>>加载程序执行模块(mod)
>>>国防部
@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'>
导入importlib.util
>>>spec=importlib.util.spec_from_file_location('a_b','/tmp/a-b.py'))
>>>mod=importlib.util.module\u from\u spec(spec)
>>>规格加载程序执行模块(mod)
>>>国防部
我用Python3.5和3.6测试了它
根据评论,它不适用于任意文件扩展名。类似于@falsetru,但适用于Python 3.5+,并说明使用
importlib.util.module\u from_spec
而非types.ModuleType时的状态:
此函数[importlib.util.module\u from_spec
]优于使用types.ModuleType
创建新的
模块as spec用于在上设置尽可能多的导入控制属性
尽可能地使用该模块
通过修改importlib.machine.SOURCE\u后缀
列表,我们可以单独导入带有importlib
的任何文件
导入导入库
importlib.machine.SOURCE_后缀.append(“”)#空字符串以允许任何文件
spec=importlib.util.spec\u from\u file\u位置(模块名称、文件路径)
module=importlib.util.module\u from_spec(spec)
规格加载器执行模块(模块)
#如果需要:importlib.machine.SOURCE_后缀.pop()
importlib
helper函数
下面是一个方便的、随时可用的帮助程序,可以用一个示例替换imp
。技术与的相同,这只是提供了一个更方便的功能
main.py
#!/usr/bin/env python3
import os
import importlib
def import_path(path):
module_name = os.path.basename(path).replace('-', '_')
spec = importlib.util.spec_from_loader(
module_name,
importlib.machinery.SourceFileLoader(module_name, path)
)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
sys.modules[module_name] = module
return module
notmain = import_path('not-main')
print(notmain)
print(notmain.x)
非主要
x = 1
运行:
输出:
<module 'not_main' from 'not-main'>
1
我不知道如何关闭它,有人问:
在Python 3.7.3中测试。Downvoter:如何改进答案?如果你有更好的方法来完成我想要的,请让我知道。有一个有用的警告,load\u module
通过warnings忽略。catch\u warnings
。如果改用mod=imp.load_source('a_b','/tmp/a-b.txt')
,则会引发以下警告(使用-Wall
):弃用警告:imp.load_source()已弃用;使用importlib.machine.SourceFileLoader(name,pathname).load_module()代替
@eryksun,没错。谢谢你的评论。顺便说一句,Python3.4(rc1)没有显示与Python3.3.x不同的替代用法。@iHavenoidia,请发布一个单独的问题,以便其他人可以回答您,其他用户也可以阅读答案。@falsetru事实上,我没有答案,到目前为止。我在这里发表评论是因为我在发表我的问题后偶然发现了你的答案。如果你知道怎么做,我会很感激的!我能问一下你为什么要这样做吗?我是importlib的维护者,我一直在试图从人们那里得到答案,他们为什么在直接的导入语句上使用imp.load\u module()
。您是否希望稍后按名称导入模块(例如,import a_b
)?您是否介意在这种方法中不使用任何自定义进口商?您是否希望该模块功能齐全(例如定义\uuuuu name\uuuuuu
和\uuuuuu loader\uuuuu
)?@BrettCannon是一个第三方程序,它定期(每小时一次)修改包含python语句的文本文件(主要是这类行的
)。文件名不以.py
结尾。我的程序读取了那个文件。@BrettCannon,我不知道自定义导入程序。我不在乎模块是全功能的。IOW使用Python作为一种非常简单的数据结构格式。谢谢你的信息@BrettCannon——我刚刚遇到一个例子,我需要从一个名为版本号的目录(例如,“v1.0.2”)中导入一些Python代码。虽然可能,但重命名目录是非常不可取的。我最后使用了下面stefan scherfke的解决方案。importlib.util.spec\u from\u file\u location(..)
为我返回None
;导致以下调用中的importlib.util.module出现异常。(请参阅)importlib.util.spec\u from_file_location
适用于已知的文件扩展名(.py
,.so
,…),但不适用于其他文件(.txt
)。哦,我只在Python文件中使用它,但修改了我的示例,使其看起来像上面的示例,并没有对其进行测试…我更新了它。很有趣,虽然这种将空字符串附加到源后缀列表的方法对于导入重命名的Python源模块非常有效,但是导入重命名的扩展模块的等效方法却不起作用。。。也就是说,使用importlib.machine.EXTENSION\u后缀.append(“”)
仍然使importlib.util.spec\u从\u文件\u位置
retu
#!/usr/bin/env python3
import os
import importlib
def import_path(path):
module_name = os.path.basename(path).replace('-', '_')
spec = importlib.util.spec_from_loader(
module_name,
importlib.machinery.SourceFileLoader(module_name, path)
)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
sys.modules[module_name] = module
return module
notmain = import_path('not-main')
print(notmain)
print(notmain.x)
x = 1
python3 main.py
<module 'not_main' from 'not-main'>
1
DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses