我需要从另一个包中动态地将模块导入到我的项目中。
结构如下:
project_folder/
project/
__init__.py
__main__.py
plugins/
__init__.py
plugin1/
__init__.py
...
plugin2/
__init__.py
...
我使用此功能加载模块:
import os
from importlib.util import spec_from_file_location, module_from_spec
def load_module(path, name=""):
""" loads a module by path """
try:
name = name if name != "" else path.split(os.sep)[-1] # take the module name by default
spec = spec_from_file_location(name, os.path.join(path, "__init__.py"))
plugin_module = module_from_spec(spec)
spec.loader.exec_module(plugin_module)
return plugin_module
except Exception as e:
print("failed to load module", path, "-->", e)
除非模块使用相对导入,否则它有效:
未能将模块/路径/加载到/ plugins / plugin1 - >父模块'plugin1'未加载,无法执行相对导入
我做错了什么?
答案 0 :(得分:14)
经过大量的谷歌搜索,我设法解决了自己的问题。结果我需要使用相对路径导入:
"bottom"
答案 1 :(得分:2)
不久前我遇到过类似的问题。我使用模块的绝对路径将项目文件夹的路径添加到sys.path中:
import sys
import os
sys.path.append(os.path.dirname(os.path.realpath(__file__))+'/..')
这会将project_folder添加到sys.path,从而允许import语句找到插件模块。
答案 2 :(得分:-3)
我们如何在importlib的官方文件中看到:
importlib.import_module(name,package = None) 导入模块。 name参数指定要以绝对或相对术语导入的模块(例如 pkg.mod或..mod )。如果名称是以相对术语指定的,那么必须将package参数指定给作为解析包名称的锚点的包(例如import_module('.. mod','pkg.subpkg')将导入pkg的.mod)。指定的模块将插入到sys.modules中并返回。
你为什么不试试?