如何加载给定完整路径的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.
其他回答
你的意思是装货还是进口?
您可以操作sys.path列表,指定模块的路径,然后导入模块。例如,给定位于以下位置的模块:
/foo/bar.py
你可以这样做:
import sys
sys.path[0:0] = ['/foo'] # Puts the /foo directory at the start of your path
import bar
您可以使用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!
如果我们在同一个项目中有脚本,但在不同的目录方式中,我们可以通过以下方法解决这个问题。
在这种情况下,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
我对@SebastianRittau的精彩回答(我认为Python>3.4)做了一个稍微修改的版本,它允许您使用spec_from_loader而不是spec_from_file_location加载具有任何扩展名的文件作为模块:
from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader
spec = spec_from_loader("module.name", SourceFileLoader("module.name", "/path/to/file.py"))
mod = module_from_spec(spec)
spec.loader.exec_module(mod)
在显式SourceFileLoader中编码路径的优点是,机器不会试图从扩展名中找出文件的类型。这意味着您可以使用此方法加载类似.txt文件的文件,但如果不指定加载器,则无法使用spec_from_file_location加载,因为.txt不在importlib.machinery.SOURCE_SUFFIX中。
我已经在此基础上放置了一个实现,@SamGrondahl对我的实用程序库haggis进行了有用的修改。该函数名为hagis.load.load_module。它添加了一些巧妙的技巧,例如在加载模块时将变量注入模块命名空间的能力。
下面是一些适用于所有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())
我测试了它。它可能很难看,但到目前为止,它是唯一一个适用于所有版本的。