【问题标题】:Plugin design question插件设计问题
【发布时间】:2011-09-25 13:05:18
【问题描述】:

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

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

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

我把所有的插件都放在了一个子文件夹里,写了一个__ init__.py来导入每个插件,然后我导入了这个文件夹(我觉得它叫包?)

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

【问题讨论】:

    标签: python plugin-architecture


    【解决方案1】:

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

    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 失败了。

    【讨论】:

    • 奇怪,这是一个奇怪的模块,我仍然喜欢这个答案。
    【解决方案2】:

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

    例如

    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

    【讨论】:

    • 比拥有单个文件夹或硬编码多个文件夹名称要灵活得多。好主意。
    猜你喜欢
    • 1970-01-01
    • 2011-01-04
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    相关资源
    最近更新 更多