如何加载给定完整路径的Python模块?
请注意,文件可以位于文件系统中用户具有访问权限的任何位置。
另请参阅:如何导入以字符串形式命名的模块?
如何加载给定完整路径的Python模块?
请注意,文件可以位于文件系统中用户具有访问权限的任何位置。
另请参阅:如何导入以字符串形式命名的模块?
当前回答
下面是一些适用于所有Python版本的代码,从2.7-3.5到其他版本。
config_file = "/tmp/config.py"
with open(config_file) as f:
code = compile(f.read(), config_file, 'exec')
exec(code, globals(), locals())
我测试了它。它可能很难看,但到目前为止,它是唯一一个适用于所有版本的。
其他回答
特殊的是使用Exec()导入具有绝对路径的模块:(exec采用代码字符串或代码对象。而eval采用表达式。)
PYMODULE = 'C:\maXbox\mX47464\maxbox4\examples\histogram15.py';
Execstring(LoadStringJ(PYMODULE));
然后使用eval()获取值或对象:
println('get module data: '+evalStr('pyplot.hist(x)'));
使用exec加载模块就像使用通配符命名空间导入:
Execstring('sys.path.append(r'+'"'+PYMODULEPATH+'")');
Execstring('from histogram import *');
这个答案是对Sebastian Rittau对评论的回答的补充:“但是如果你没有模块名怎么办?”这是一种快速而肮脏的方法,可以将可能的Python模块名指定为文件名——它只是沿着树向上移动,直到找到一个没有__init__.py文件的目录,然后将其转换回文件名。对于Python 3.4+(使用pathlib),这是有意义的,因为Python 2可以使用“imp”或其他方式进行相对导入:
import pathlib
def likely_python_module(filename):
'''
Given a filename or Path, return the "likely" python module name. That is, iterate
the parent directories until it doesn't contain an __init__.py file.
:rtype: str
'''
p = pathlib.Path(filename).resolve()
paths = []
if p.name != '__init__.py':
paths.append(p.stem)
while True:
p = p.parent
if not p:
break
if not p.is_dir():
break
inits = [f for f in p.iterdir() if f.name == '__init__.py']
if not inits:
break
paths.append(p.stem)
return '.'.join(reversed(paths))
当然有改进的可能性,可选的__init__.py文件可能需要进行其他更改,但如果您通常有__init__.pry,这就有了窍门。
我并不是说它更好,但为了完整起见,我想建议在Python2和Python3中使用exec函数。
exec允许您在全局作用域或作为字典提供的内部作用域中执行任意代码。
例如,如果您有一个模块存储在带有函数foo()的“/path/to/module”中,您可以通过执行以下操作来运行它:
module = dict()
with open("/path/to/module") as f:
exec(f.read(), module)
module['foo']()
这使得动态加载代码更加明确,并赋予您一些额外的功能,例如提供自定义内置功能的能力。
如果通过属性而不是键访问对你来说很重要,你可以为全局变量设计一个自定义dict类,提供这样的访问,例如:
class MyModuleClass(dict):
def __getattr__(self, name):
return self.__getitem__(name)
如果我们在同一个项目中有脚本,但在不同的目录方式中,我们可以通过以下方法解决这个问题。
在这种情况下,utils.py位于src/main/util中/
import sys
sys.path.append('./')
import src.main.util.utils
#or
from src.main.util.utils import json_converter # json_converter is example method
我相信您可以使用imp.find_module()和imp.load_module)来加载指定的模块。您需要将模块名称从路径中分离出来,即,如果要加载/home/mypath/mymodule.py,则需要执行以下操作:
imp.find_module('mymodule', '/home/mypath/')
…但这应该能完成任务。