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