使用Python动态导入包含多个文件的包

时间:2015-04-15 09:04:44

标签: python python-2.7 import module

我正在尝试在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__方法或其他方法?

1 个答案:

答案 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)