Python 鈎子函數詳解


#### 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
```

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM