如何加载给定完整路径的Python模块?
请注意,文件可以位于文件系统中用户具有访问权限的任何位置。
另请参阅:如何导入以字符串形式命名的模块?
如何加载给定完整路径的Python模块?
请注意,文件可以位于文件系统中用户具有访问权限的任何位置。
另请参阅:如何导入以字符串形式命名的模块?
当前回答
对于Python 3.5+,使用(docs):
import importlib.util
import sys
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
sys.modules["module.name"] = foo
spec.loader.exec_module(foo)
foo.MyClass()
对于Python 3.3和3.4,请使用:
from importlib.machinery import SourceFileLoader
foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()
(尽管Python 3.4中已弃用此选项。)
对于Python 2,请使用:
import imp
foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()
编译后的Python文件和DLL有等效的方便函数。
另请参见http://bugs.python.org/issue21436.
其他回答
如果我们在同一个项目中有脚本,但在不同的目录方式中,我们可以通过以下方法解决这个问题。
在这种情况下,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
这应该行得通
path = os.path.join('./path/to/folder/with/py/files', '*.py')
for infile in glob.glob(path):
basename = os.path.basename(infile)
basename_without_extension = basename[:-3]
# http://docs.python.org/library/imp.html?highlight=imp#module-imp
imp.load_source(basename_without_extension, infile)
这个答案是对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,这就有了窍门。
为了补充塞巴斯蒂安·里托的回答:至少对于CPython,有pydoc,虽然没有正式声明,但导入文件就是它的作用:
from pydoc import importfile
module = importfile('/path/to/module.py')
PS。为了完整起见,在撰写本文时,这里提到了当前的实现:pydoc.py,我很高兴地说,在xkcd 1987的脉络中,它没有使用第21436期中提到的任何一个实现,至少没有逐字逐句地使用。
你的意思是装货还是进口?
您可以操作sys.path列表,指定模块的路径,然后导入模块。例如,给定位于以下位置的模块:
/foo/bar.py
你可以这样做:
import sys
sys.path[0:0] = ['/foo'] # Puts the /foo directory at the start of your path
import bar