我有一个用Python编写的应用程序,它是由相当专业的观众(科学家)使用的。
我正在寻找一个好方法,使应用程序可扩展的用户,即脚本/插件架构。
I am looking for something extremely lightweight. Most scripts, or plugins, are not going to be developed and distributed by a third-party and installed, but are going to be something whipped up by a user in a few minutes to automate a repeating task, add support for a file format, etc. So plugins should have the absolute minimum boilerplate code, and require no 'installation' other than copying to a folder (so something like setuptools entry points, or the Zope plugin architecture seems like too much.)
是否已经有类似的系统存在,或者是否有项目实现了类似的方案,我应该看看想法/灵感?
扩展@edomaur的回答,我建议看看simple_plugins(无耻的插件),这是一个简单的插件框架,灵感来自Marty Alchin的工作。
一个基于项目README的简短使用示例:
# All plugin info
>>> BaseHttpResponse.plugins.keys()
['valid_ids', 'instances_sorted_by_id', 'id_to_class', 'instances',
'classes', 'class_to_id', 'id_to_instance']
# Plugin info can be accessed using either dict...
>>> BaseHttpResponse.plugins['valid_ids']
set([304, 400, 404, 200, 301])
# ... or object notation
>>> BaseHttpResponse.plugins.valid_ids
set([304, 400, 404, 200, 301])
>>> BaseHttpResponse.plugins.classes
set([<class '__main__.NotFound'>, <class '__main__.OK'>,
<class '__main__.NotModified'>, <class '__main__.BadRequest'>,
<class '__main__.MovedPermanently'>])
>>> BaseHttpResponse.plugins.id_to_class[200]
<class '__main__.OK'>
>>> BaseHttpResponse.plugins.id_to_instance[200]
<OK: 200>
>>> BaseHttpResponse.plugins.instances_sorted_by_id
[<OK: 200>, <MovedPermanently: 301>, <NotModified: 304>, <BadRequest: 400>, <NotFound: 404>]
# Coerce the passed value into the right instance
>>> BaseHttpResponse.coerce(200)
<OK: 200>
在我们当前的医疗保健产品中,我们有一个用接口类实现的插件体系结构。我们的技术栈是Django在Python之上的API, Nuxtjs在nodejs之上的前端。
我们为我们的产品编写了一个插件管理器应用程序,它基本上是pip和npm包,遵循Django和Nuxtjs。
对于新插件开发(pip和npm),我们将插件管理器作为依赖项。
在Pip软件包中:
在setup.py的帮助下,你可以添加插件的入口点,用插件管理器做一些事情(注册表,初始化,等等)。
https://setuptools.readthedocs.io/en/latest/setuptools.html#automatic-script-creation
在npm包中:
与pip类似,npm脚本中有钩子来处理安装。
https://docs.npmjs.com/misc/scripts
我们的usecase:
现在插件开发团队与核心开发团队是分开的。插件开发的范围是与第三方应用程序集成,这些应用程序定义在产品的任何类别中。插件接口分类如下:-传真,电话,电子邮件…等插件管理器可以增强到新的类别。
在你的情况下:也许你可以写一个插件,然后重复使用它来做一些事情。
如果插件开发人员需要使用重用核心对象,可以通过在插件管理器中进行抽象级别来使用该对象,以便任何插件都可以继承这些方法。
只是分享一下我们是如何在我们的产品中实现的,希望能给大家一点启发。
您可以使用pluginlib。
插件很容易创建,并且可以从其他包、文件路径或入口点加载。
创建一个插件父类,定义所需的方法:
import pluginlib
@pluginlib.Parent('parser')
class Parser(object):
@pluginlib.abstractmethod
def parse(self, string):
pass
通过继承父类创建插件:
import json
class JSON(Parser):
_alias_ = 'json'
def parse(self, string):
return json.loads(string)
加载插件:
loader = pluginlib.PluginLoader(modules=['sample_plugins'])
plugins = loader.plugins
parser = plugins.parser.json()
print(parser.parse('{"json": "test"}'))