我正在开展一个项目,其主要设计指导原则是可扩展性。
我通过定义一个元类来实现一个插件系统,该元类使用类方法注册任何加载的插件的类名(每种类型的插件都继承自核心中定义的特定类代码,因为应用程序中有不同类型的插件)。基本上这意味着开发人员必须将他的类定义为
class PieChart(ChartPluginAncestor):
# Duck typing:
# Implement compulsory methods for Plugins
# extending Chart functionality
主程序将知道他的存在,因为PieChart
将包含在ChartPluginAncestor.plugins
可用的已注册插件列表中。
作为一种类方法的挂载方法,所有插件在其类代码加载到内存时都会被注册(因此甚至在实例化该类的对象之前)。
系统对我来说足够好™(虽然我总是乐于接受如何改进架构的建议!)但我现在想知道管理插件文件的最佳方法是什么(即应该存储包含插件的文件的位置和方式)。
到目前为止,我正在使用 - 用于开发目的 - 我称之为“插件”的包。我将包含插件类的所有* .py文件放在包目录中,我只需在main.py文件中发出import plugins
,以便正确安装所有插件。
编辑:杰夫在评论中指出import plugins
包的各个模块中包含的类将不会随时可用(我没有意识到这一点 - 我是 - 出于调试目的 - 使用from plugins.myAI import AI
分别导入每个类。
然而,在我开发和测试代码时,这个系统才有用,如:
/usr/local/bin/
下的某个位置)和特定于用户的位置(例如{{1}下的某处) })。所以我的问题确实 - 或许 - 三:
答案 0 :(得分:3)
这个问题很难解决,因为需求很复杂。 无论如何,我会尝试一些建议。
关于
将插件分为两种不同的插件 位置:有标准方式/ 最佳实践(在gnu / linux下,at 至少)这样做?
一个好的方法是virtualenv。 Virtualenv是一个用于构建“隔离”python安装的python模块。这是让单独项目协同工作的更好方法。 您将获得一个全新的站点包,您可以将插件与相关的项目模块放在一起。
试一试:http://pypi.python.org/pypi/virtualenv
插件容器:最多的是什么 我目标明智的选择?单 文件?包?一个简单的目录 .py文件?)
一个好的方法是一个python包,它可以在导入时进行“自我注册”:只需在包目录中定义一个正确的 init .py
示例可以是http://www.qgis.org/wiki/Writing_Python_Plugins 以及此处描述的API http://twistedmatrix.com/documents/current/core/howto/plugin.html
另见http://pypi.python.org/pypi/giblets/0.2.1
Giblets是一个简单的插件系统 基于组件架构 Trac的。简而言之,内脏允许 你要声明接口并发现 没有实现它们的组件 耦合。
Giblets还包括插件发现 基于文件路径或入口点 以及灵活的管理手段 哪些组件已启用或 在您的申请中被禁用。
答案 1 :(得分:1)
我还有一个插件系统有三种类型的插件,但我并没有声称已经做得很好。您可以看到一些详细信息here。
对于内部插件,我有一个包(例如MethodPlugins
),在这个包中是每个插件的模块(例如MethodPlugins.IRV
)。以下是我加载插件的方法:
加载包裹(import MethodPlugins
)
使用pkgutil.iter_modules
加载那里的所有模块(例如MethodPlugins.IRV
)
所有插件都来自公共基类,因此我可以使用__subclassess__
来识别它们。
我相信这可以让你识别插件而不会实际加载它们,虽然我不这样做,因为我只是加载它们。
对于外部插件,我有一个用户可以放置它们的指定目录,我使用os.listdir
来导入它们。用户需要使用正确的基类,以便我找到它们。
我也有兴趣改进它,但它对我来说也足够好。 :)