插件设计问题

时间:2011-06-29 21:55:35

标签: python plugin-architecture

我的程序分为两部分:引擎,处理用户界面和其他“主程序”的东西,以及一组插件,提供处理特定输入的方法。

每个插件都在自己的模块中编写,并提供了一个允许我向插件发送数据和从插件中检索数据的函数。

这个函数的名称在所有插件中是相同的,所以我需要的是确定要调用哪一个,然后插件将处理其余的。

我已将所有插件放在子文件夹中,写了导入每个插件的__ init__.py,然后导入文件夹(我认为它叫做包?)

无论如何,目前我明确告诉它要导入什么(基本上是“导入此”,“导入”)。有没有办法让我编写它以便它将导入该插件的文件夹中的所有内容,以便我可以添加其他插件而无需编辑init文件?

2 个答案:

答案 0 :(得分:2)

以下是我用来执行此操作的代码:

def _loadPackagePlugins(package):
  "Load plugins from a specified package."
  ppath = package.__path__
  pname = package.__name__ + "."
  for importer, modname, ispkg in pkgutil.iter_modules(ppath, pname):
    module = __import__(modname, fromlist = "dummy")

与Jakob的答案的主要区别在于它使用pkgutil.iter_modules而不是os.listdir。我曾经使用os.listdir并改为以这种方式做,但我不记得为什么。当我用py2exe和py2app打包我的应用程序时,可能是os.listdir失败了。

答案 1 :(得分:1)

你总是可以有一个名为plugins的字典,使用__import__导入模块并以这种方式存储它们。

e.g。

plugins = {}
for plugin in os.listdir('plugins'):
    plugin = plugin.split()[0]
    plugins[plugin] = __import__(plugin)

这假设每个插件都是单个文件。就个人而言,我会选择在每个文件夹中查找__run__.py文件的内容,就像它指示插件的包中的__init__.py一样,该代码看起来更像是这样的

for root, dirs, files in os.walk('.'):
    for dir in dirs:
        if "__run__.py" in os.listdir(os.path.join(root, dir)):
            plugins[dir] = __import__(dir)

未经测试编写的代码。 YMMV