#### pluggy為插件系統 1、PluginManager:用於管理插件規范和插件本身 2、HookspecMarker:給裝飾的函數增加額外的屬性和規則,不符合這個規則的會報錯,如果這里定義函數有參數a,b,hookimpl中的參數必需為a,b子集並且名稱相同 3、HookimplMarker:定義插件,插件邏輯具體實現在該類裝飾的方法中 ``` import pluggy #創建規范裝飾器 hookspec = pluggy.HookspecMarker('aaa') #創建插件類裝飾器 hookimpl = pluggy.HookimplMarker('aaa') class MySpec(): @hookspec() # firstresult=True設置之后,等到第一個返回非空結果的hookimpl,就返回(hookwrapper還是正常執行) def myhook(self, arg_one, arg_two): pass class MyPlugin(): @hookimpl() # tryfirst=True,trylast=True定義執行順序 def myhook(self, arg_one): print('arg_one') return arg_one class MyPluginOther(): @hookimpl() def myhook(self, arg_one, arg_two): print('arg_one, arg_two') return arg_one, arg_two class MyPluginWrapper(): ''' hookwrapper作為每個鈎子函數的上下文運行 在所有hook之前先運行 ''' @hookimpl(hookwrapper=True) def myhook(self): print('-------- hool wrapper before -----------') outcome = yield # 生成器會給outcome send一個pluggy.callers._Result對象 print('-------- hook wrapper after -----------') res = outcome.get_result() # 通過get_result拿到所有鈎子函數的結果 print('get all hook return ', res) outcome.force_result(1) # 強制更改鈎子函數返回結果 print('-------- hook wrapper end-----------') test1 = pluggy.PluginManager('aaa') #用於把構建注冊到test1,然后test1統一調用myhook鈎子函數,收集鈎子函數的return結果 ‘aaa'為project_name要統一 test1.add_hookspecs(MySpec) test1.register(MyPlugin()) test1.register(MyPluginOther()) # 后注冊的先執行,收集進結果 test1.register(MyPluginWrapper()) result = test1.hook.myhook(arg_one=1, arg_two=2) # hookimpl調用,必須用關鍵字語法 print(result) ------------------ 輸出結果: -------- hool wrapper before ----------- arg_one, arg_two arg_one -------- hook wrapper after ----------- get all hook return [(1, 2), 1] -------- hook wrapper end----------- 1 ```