如何组织我已经工作的插件系统的文件结构?

2024-10-04 01:28:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做一个项目,其主要设计指导原则是可扩展性。在

我通过定义一个元类来实现一个插件系统,该元类用类方法注册加载的任何插件的类名(每种类型的插件继承自核心代码中定义的特定类,因为应用程序中有不同类型的插件)。基本上这意味着开发人员必须将他的类定义为

class PieChart(ChartPluginAncestor):
    # Duck typing:
    # Implement compulsory methods for Plugins 
    # extending Chart functionality

主程序将知道他的存在,因为PieChart将包含在ChartPluginAncestor.plugins上的已注册插件列表中。在

由于挂载方法是一个类方法,所有的插件都会在其类代码加载到内存中时注册(因此即使在实例化该类的对象之前也是如此)。在

系统运行良好™ 对我来说(尽管我总是乐于接受关于如何改进体系结构的建议!)但是我现在想知道什么是管理插件文件的最佳方式(即包含插件的文件应该存储在哪里和如何存储)。在

到目前为止,为了开发目的,我使用了一个我称之为“插件”的包。我把所有包含插件类的*.py文件放在包目录中,然后在主.py文件,以便所有插件都能正确安装。在

编辑:Jeff在评论中指出import plugins包的各个模块中包含的类将不容易获得(我没有意识到这一点,因为我是为了调试目的,使用from plugins.myAI import AI分别导入每个类)。在

但是,这个系统只有在我开发和测试代码时才是好的,因为:

  • 插件可能有自己的单元测试,我不想在内存中加载它们。在
  • 所有的插件目前都被加载到内存中,但是确实有一些插件是同一特性的替代版本,所以你只需要知道你可以在这两个插件之间切换,但是你只想将你从配置面板中选择的插件加载到内存中。在
  • 在某种程度上,我希望有一个双重位置来安装插件:一个系统范围的位置(例如/usr/local/bin/)和一个特定于用户的位置(例如/home/<user>/.myprogram/下的某个位置)。在

所以我的问题真的-也许-三个:

  1. 插件容器:对于我的目标,什么是最明智的选择?单个文件?包装?一个简单的.py文件目录?)在
  2. 在不必加载(导入)插件的情况下识别插件的存在:使用Python自省的聪明方法是什么?在
  3. 将插件放在两个不同的位置:是否有一种标准的方法/最佳实践(至少在gnu/linux下)来实现这一点?在

Tags: 文件项目方法内存代码pyimport目的
2条回答

我也有一个插件系统,有三种类型的插件,尽管我并不声称做得很好。您可以看到一些细节here。在

对于内部插件,我有一个包(例如,MethodPlugins),在这个包中是每个插件的一个模块(例如,MethodPlugins.IRV)。下面是我如何加载插件:

  1. 加载包(import MethodPlugins

  2. 使用pkgutil.iter_modules加载那里的所有模块(例如,MethodPlugins.IRV

  3. 所有插件都来自一个公共基类,所以我可以使用__subclassess__来标识它们。

我相信这可以让你在不加载插件的情况下识别插件,尽管我不这么做,因为我只是把它们全部加载。在

对于外部插件,我有一个用户可以放置它们的指定目录,我使用os.listdir导入它们。用户需要使用正确的基类,这样我才能找到它们。在

我也有兴趣改进这一点,但它对我来说也足够好了。:)

这个问题很难解决,因为需求很复杂。 不管怎样,我会试着提出一些建议。在

关于

Placing plugins in two different locations: is there a standard way / best practice (under gnu/linux, at least) to do that?

一个好的方法是virtualenv。Virtualenv是一个python模块,用于构建“独立的”python安装。这是让不同项目协同工作的更好方法。 你得到了一个全新的网站包,你可以把你的插件与相关的项目模块。在

试试看:http://pypi.python.org/pypi/virtualenv

Plugin container: what is the most sensible choice for my goal? single files? packages? a simple directory of .py files?)

一个好的方法是一个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 is a simple plugin system based on the component architecture of Trac. In a nutshell, giblets allows you to declare interfaces and discover components that implement them without coupling.

Giblets also includes plugin discovery based on file paths or entry points along with flexible means to manage which components are enabled or disabled in your application.

相关问题 更多 >