python 優雅地實現外掛程式架構

2021-09-07 10:22:42 字數 2741 閱讀 6550

近日,決定用 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,在程式中使用外掛程式,需要引...