场景如下:
我正在构建一个将外部脚本用作插件的框架。人们将能够为符合某些接口的脚本创建“适配器”。这些适配器将被集成到框架中(因此需要插件注册)或通过简单的导入“松散地”使用。
换句话说,适配器用于脚本使用标准化。
我可能想得太复杂了,但我目前正在使用的解决方案涉及创建一个定义接口(和一些实用方法)的抽象类。抽象类的模块将只加载一次,框架将加载一个带有自注册元类的版本,而插件本身将加载一个更简单的版本(第一个注册抽象类的版本获胜)。
这迫使插件有一个定义抽象类的文件,因此是“合同”。我看不出有什么问题。
我不会真的有两个不同的抽象类,而是一个模块文件中的一个,它的行为取决于它的加载位置(框架或插件本身)。但这不应该是相关的(我认为)。
这就是抽象类/元类的样子
#imp/plugin.py
import abc
class PluginAbstract(object):
class __metaclass__(abc.ABCMeta):
def __init__(self, name, bases, namespace):
if name != 'PluginAbstract':
pass #We can register the new "sub-class" if required
return abc.ABCMeta.__init__(abc.ABCMeta, name, bases, namespace)
实现将类似于:
#impl/MyPlugin.py
if 'plugin' not in locals():
from impl import plugin
class MyPlugin(plugin.PluginAbstract):
pass #rest of the implementation....
因此,如果框架已经注册PluginAbstract
,则将继承该框架,否则将使用合同文件中的那个。 impl/plugin.py
我不希望适配器需要安装框架,因此需要安装带有接口的单个文件。
这个策略有意义吗?还有其他选择吗?