最近在看一个pyqt写的工具软件,项目中大量使用plugins,所以了解了一下plugins的功能机制。下面简单分享一个例程,代码结构如下
|- main.py
|- platform.py
|- __init__.py
|- plugins
|- __init__.py
|- plugin1.py
|- plugin2.py
1. main.py中创建TextProcessor,然后将plugin1和plugin2插入。需要注意,
1)在import TextProcessor时,plugin1和plugin2已经注册到TextProcessor的PLUGINS中了
2)plugin1、plugin2必须与插件类中@TextProcessor.plugin_register('xxx')一致
from scripts.platform import TextProcessor
if __name__ == '__main__':
processor = TextProcessor()
print processor.PLUGINS
processed = processor.process(text='**foo bar**', plugins=('plugin1', 'plugin2'))
2. platform.py中,PLUGINS存储的时插件的内容,process函数是执行插件内容;plugin_register是在插件类创建时注册到PLUGINS中。
class TextProcessor(object):
PLUGINS = {}
def process(self, text, plugins=()):
if plugins is ():
for plugin_name in self.PLUGINS.keys():
result = self.PLUGINS[plugin_name]().process(text)
else:
for plugin_name in plugins:
result = self.PLUGINS[plugin_name]().process(text)
return result
@classmethod
def plugin_register(cls, plugin_name):
def wrapper(plugin):
print 'update {}'.format(plugin_name)
cls.PLUGINS.update({plugin_name: plugin})
return wrapper
3. __init__.py中将plugins中的类导入,注意这行是platform.py中注册时使用,为什么不在platform.py中导入,这是因为plugin1.py中需要导入platform的类,为了避免重复导入。
from plugins import *
4. plugins包中,放的所有插件具体的操作
4.1 __init__.py中,将所有插件库放入其中,避免platform.py注册时无法找到对应插件类
__all__ = ['plugin1', 'plugin2']
4.2 plugin1.py中,通过@TextProcessor.plugin_register('plugin1')将plugin1插入到TextProcessor.PLUGINS中。
from ..platform import TextProcessor
@TextProcessor.plugin_register('plugin1')
class CleanMarkdownBolds(object):
def process(self, text):
print (text.replace('**', '!!!'))
return 0
4.3 plugin2.py中,将plugin2插入到TextProcessor.PLUGINS中。
from ..platform import TextProcessor
@TextProcessor.plugin_register('plugin2')
class CleanMarkdownBolds(object):
def process(self, text):
print (text.replace('**', '???'))
return 0
最后执行main.py,代码逻辑是导入TextProcessor类时,会导入plugins库,这时各插件类会通过@TextProcessor.plugin_register将插件类插入TextProcessor.PLUGINS中,最后通过processor.process(text='**foo bar**', plugins=('plugin1', 'plugin2'))执行所有插件内容。