我正在从事一个项目,其主要设计指导原则是可扩展性。
我通过定义一个元类来实现一个插件系统,该元类使用类方法注册任何加载的插件的类名(每种类型的插件都继承自核心代码中定义的特定类,因为有不同类型的插件在应用程序)。基本上这意味着开发人员必须将他的类定义为
class PieChart(ChartPluginAncestor):
# Duck typing:
# Implement compulsory methods for Plugins
# extending Chart functionality
并且主程序将知道他的存在,因为PieChart
将包含在可用的注册插件列表中ChartPluginAncestor.plugins
。
作为类方法的挂载方法,所有插件在其类代码加载到内存时都会被注册(甚至在该类的对象被实例化之前)。
该系统对我来说足够好™(尽管我总是对如何改进体系结构的建议持开放态度!)但我现在想知道管理插件文件的最佳方法是什么(即包含插件的文件在哪里以及如何应储存)。
到目前为止,我正在使用 - 出于开发目的 - 我称之为“插件”的包。我将所有包含插件类的 *.py 文件放在包目录中,我只是import plugins
在 main.py 文件中发出,以便所有插件都能正确安装。
编辑:杰夫在评论中指出,import plugins
包的各个模块中包含的类不会很容易获得(我没有意识到这一点 - 出于调试目的 - 分别导入每个类from plugins.myAI import AI
)。
然而,这个系统只有在我开发和测试代码时才好用,因为:
- 插件可能带有自己的单元测试,我不想将它们加载到内存中。
- 所有插件当前都加载到内存中,但确实有某些插件是相同功能的替代版本,所以你真的只需要知道你可以在两者之间切换,但你只想加载你选择的那个从配置窗格。
- 在某些时候,我会希望有一个安装插件的双重位置:一个系统范围的位置(例如在某处
/usr/local/bin/
)和一个特定于用户的位置(例如在某处/home/<user>/.myprogram/
)。
所以我的问题真的是——也许——三个:
- 插件容器:我的目标最明智的选择是什么?单个文件?包?.py 文件的简单目录?)
- 识别插件的存在而不必加载(导入)它们:使用 Python 内省来做到这一点的聪明方法是什么?
- 将插件放置在两个不同的位置:是否有标准的方法/最佳实践(至少在 gnu/linux 下)可以做到这一点?