如何加载给定完整路径的Python模块?
请注意,文件可以位于文件系统中用户具有访问权限的任何位置。
另请参阅:如何导入以字符串形式命名的模块?
如何加载给定完整路径的Python模块?
请注意,文件可以位于文件系统中用户具有访问权限的任何位置。
另请参阅:如何导入以字符串形式命名的模块?
当前回答
这个答案是对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,这就有了窍门。
其他回答
要导入模块,需要将其目录临时或永久添加到环境变量中。
暂时
import sys
sys.path.append("/path/to/my/modules/")
import my_module
永久地
在Linux中将以下行添加到.bashrc(或替代)文件中以及终端中的exccute source~/.bashrc(或替代):
export PYTHONPATH="${PYTHONPATH}:/path/to/my/modules/"
信贷/来源:saarrrr,另一个Stack Exchange问题
特殊的是使用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 *');
我认为,最好的方法是从官方文件(29.1。imp-访问导入内部构件):
import imp
import sys
def __import__(name, globals=None, locals=None, fromlist=None):
# Fast path: see if the module has already been imported.
try:
return sys.modules[name]
except KeyError:
pass
# If any of the following calls raises an exception,
# there's a problem we can't handle -- let the caller handle it.
fp, pathname, description = imp.find_module(name)
try:
return imp.load_module(name, fp, pathname, description)
finally:
# Since we may exit via an exception, close fp explicitly.
if fp:
fp.close()
我并不是说它更好,但为了完整起见,我想建议在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)
您可以使用pkgutil模块(特别是walk_packages方法)获取当前目录中的包列表。从那里,使用importlib机制导入所需的模块很简单:
import pkgutil
import importlib
packages = pkgutil.walk_packages(path='.')
for importer, name, is_package in packages:
mod = importlib.import_module(name)
# do whatever you want with module now, it's been imported!