近日,決定用 python 實現外掛程式架構,於是上 stackoverflow 逛了一下,在這裡發現一段**,非常喜歡。
**先貼出來,以饗觀眾:
''' 外掛程式架構 '''
# 平台
class textprocessor(object):
plugins = {}
def process(self, text, plugins=()):
if plugins is ():
for plugin_name in self.plugins.keys():
text = self.plugins[plugin_name]().process(text)
else:
for plugin_name in plugins:
text = self.plugins[plugin_name]().process(text)
return text
@classmethod
def plugin_register(cls, plugin_name):
cls.plugins.update()
return plugin
# 外掛程式
@textprocessor.plugin_register('plugin1')
class cleanmarkdownbolds(object):
def process(self, text):
return text.replace('**', '')
# 測試
processor = textprocessor()
print(processor.plugins) #
processed = processor.process(text="**foo bar**", plugins=('plugin1', ))
processed = processor.process(text="**foo bar**")
這段**執行良好!但是它是單檔案,不適合實際使用。
在實際專案中,上面的三個注釋下面的部分一定是拆開的,其中外掛程式一般都約定俗成地放到 plugins 子目錄下。
為了實現這個想法,走了很多彎路,花了兩天時間!這期間查閱了__metaclass__
原理,__subclass__()
函式, package的組織方式等等。最後真的靈光一閃,成功實現!
專案結構:
├─ myproject
├─ run.py
├─ __init__.py
├─ main.py
├─ platform.py
├─ plugins
├─ __init__.py
├─ plugin1.py
├─ plugin2.py
完整**
class textprocessor(object):
plugins = {}
def process(self, text, plugins=()):
if plugins is ():
for plugin_name in self.plugins.keys():
text = self.plugins[plugin_name]().process(text)
else:
for plugin_name in plugins:
text = self.plugins[plugin_name]().process(text)
return text
@classmethod
def plugin_register(cls, plugin_name):
cls.plugins.update()
return plugin
from ..platform import textprocessor
@textprocessor.plugin_register('plugin1')
class cleanmarkdownbolds(object):
def process(self, text):
return text.replace('**', '')
# 第二個外掛程式!
from ..platform import textprocessor
@textprocessor.plugin_register('plugin2')
class cleanmarkdownitalic(object):
def process(self, text):
return text.replace('--', '')
from .platform import textprocessor
def test():
processor = textprocessor()
print(processor.plugins) #
processed = processor.process(text="**foo bar**", plugins=('plugin1', ))
processed = processor.process(text="--foo bar--")
from .plugins import *
__all__ = ['plugin1', 'plugin2']
# mpyproject/run.py
test()
外掛程式是冷插拔的
外掛程式不是懶載入
python 優雅地實現外掛程式架構
近日,決定用 python 實現外掛程式架構,於是上 stackoverflow 逛了一下,在這裡發現一段 非常喜歡。提醒各位大俠注意,我對這段 作了一點小小的改動 原plugins是 list 物件,改動後plugins是 dict 物件。先貼出來,以饗觀眾 外掛程式架構 平台 class tex...
如何較為優雅地實現新手引導功能?
早期的專案中曉衡遇到遊戲終於要完成了,辛苦了一陣滿以為可以稍微放鬆一下了,但策劃 運營要求,增加乙個他們認為非常 簡單 且重要的功能 新手引導。回想起當年,接到這個任務時的感覺是手腳冒汗 天暈地暗 日月無光,遊戲 本來就千瘡面孔,邏輯錯綜複雜,根本不知道該怎麼下手?更困難的是,遊戲本身功能和需求還不...
C 實現外掛程式式架構
1.定義外掛程式介面,將其編譯為dll namespace plugininte ce 2 編寫外掛程式,引用上面的dll,實現上面定義的介面,也編譯為dll 外掛程式a namespace plugininte ce 外掛程式b namespace pluginb 3,在程式中使用外掛程式,需要引...