我正在尝试在python中动态导入模块。 我需要像插件导入系统这样的东西。
我使用以下代码导入模块,只要模块的整个代码在同一个文件中,它就可以正常工作。
caller.py
代码:
PluginFolder = "./plugins"
MainModule = "__init__"
possibleplugins = os.listdir(PluginFolder)
for possible_plugin in possibleplugins:
location = os.path.abspath(os.path.join(PluginFolder, possible_plugin))
if not os.path.isdir(location) or not MainModule + ".py" in os.listdir(location):
continue
info = imp.find_module(MainModule, [location])
plugin = {"name": possible_plugin, "info": info}
之后,我使用load_module方法加载模块:
module = imp.load_module(MainModule, *plugin["info"])
目录的结构如下:
Project/
--plugins/
----plugin_1/
-------__init__.py
-------X.py
caller.py
当所有方法都在同一个文件(__init__.py
)中时,一切都很有用。
当我在__init__.py
中使用的方法从另一个文件(在同一个包中)调用另一个方法而不是错误说"没有名为X&#34的模块;
__init__.py
代码在该行失败:
import X
我也试过
import plugin_1.X
和其他变化。
只是为了确保你们理解 - 以正常方式(非动态)导入和使用模块可以正常工作。
我错过了什么?
还有另一种方法吗?也许使用__import__
方法或其他方法?
答案 0 :(得分:0)
我通常使用importlib
。这是load_module
方法完成工作。您可以将导入代码放入plugins/__init__.py
以执行以下操作:
import importlib
import os
import logging
skip = set(("__init__.py",))
plugins = []
cwd = os.getcwd()
os.chdir(os.path.dirname(__file__))
for mod in glob.glob("*.py"):
if mod in skip:
continue
try:
mod = mod.replace(".py", "")
plugin = importlib.import_module("." + mod, __name__)
plugin.append(plugin)
except Exception as e:
logging.warn("Failed to load %s: %s. Skipping", mod, e)
os.chdir(cwd)