Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import pluggy
hookspec = pluggy.HookspecMarker("myproject") hookimpl = pluggy.HookimplMarker("myproject")
class MyHooks: @hookspec def cal(self, arg1, arg2): """计算 hook 的声明"""
class Plugin1:
@hookimpl def cal(self, arg1, arg2): """ 加法hook的实现""" print("do plugin1 hook") return arg1 + arg2
class Plugin2:
@hookimpl def cal(self, arg1, arg2): """ 减法hook的实现""" print("do plugin2 hook") return arg1 - arg2 pm = pluggy.PluginManager("myproject") pm.add_hookspecs(MyHooks)
pm.register(Plugin1()) pm.register(Plugin2())
results = pm.hook.cal(arg1=1, arg2=2) print(results)
do plugin2 hook do plugin1 hook [-1, 3]
|
后注册的先执行 所以plugin2 比plugin1 先执行
hook 和插件是1:N的关系 注册了多个plugin就会返回多个plugin 的结果
装饰器参数
tryfirst 和 trylast
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import pluggy
hookspec = pluggy.HookspecMarker("myproject") hookimpl = pluggy.HookimplMarker("myproject")
class MyHooks: @hookspec def cal(self, arg1, arg2): """计算 hook 的声明""" class Plugin1: @hookimpl(tryfirst=True) def cal(self, arg1, arg2): """ 加法hook的实现""" print("do plugin1 hook") return arg1 + arg2 class Plugin2: @hookimpl def cal(self, arg1, arg2): """ 减法hook的实现""" print("do plugin2 hook") return arg1 - arg2
pm = pluggy.PluginManager("myproject") pm.add_hookspecs(MyHooks)
pm.register(Plugin1()) pm.register(Plugin2())
results = pm.hook.cal(arg1=1, arg2=2) print(results) do plugin1 hook do plugin2 hook [3, -1]
|
如果标记了tryfirst或者trylast选项就会在hook的call loop 中 第一个执行或最后一个执行;默认情况是基于注册顺序的LIFO来调用的,如果你想要改变他们的调用顺序
hookwrapper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| import pluggy
hookspec = pluggy.HookspecMarker("myproject") hookimpl = pluggy.HookimplMarker("myproject") class MyHooks: @hookspec def cal(self, arg1, arg2): """计算 hook 的声明"""
class Plugin1: @hookimpl def cal(self, arg1, arg2): """ 加法hook的实现""" print("do plugin1 hook") return arg1 + arg2
class Plugin2: @hookimpl def cal(self, arg1, arg2): """ 减法hook的实现""" print("do plugin2 hook") return arg1 - arg2
class WrapperPlugin: @hookimpl(hookwrapper=True) def cal(self, arg1, arg2): """ wrapperhook的实现""" print("do wrapperplugin") print("before yield") ret = yield print(f"after yield ret is {ret.get_result()}") return 1000
pm = pluggy.PluginManager("myproject") pm.add_hookspecs(MyHooks)
pm.register(Plugin1()) pm.register(Plugin2()) pm.register(WrapperPlugin())
results = pm.hook.cal(arg1=1, arg2=2) print(results)
do wrapperplugin before yield do plugin2 hook do plugin1 hook after yield ret is [-1, 3] [-1, 3]
|
一个hookimpl被标记hookwrapper参数,意味着这个函数被调用在其他正常hookimpl的的前后; yield 之前的代码先执行然后执行其他的hookimpl, 其他的hookimpl执行结束就会执行yield之后的代码 而被标记hookwrapper参数的hookimpl的返回值被忽略了(@hookimpl(wrapper=True) 是一样的 老版本风格)
firstresult
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| import pluggy
hookspec = pluggy.HookspecMarker("myproject") hookimpl = pluggy.HookimplMarker("myproject")
class MyHooks: @hookspec(firstresult=True) def cal(self, arg1, arg2): """计算 hook 的声明"""
class Plugin1: @hookimpl() def cal(self, arg1, arg2): """ 加法hook的实现""" print("do plugin1 hook") return arg1 + arg2 class Plugin2: @hookimpl def cal(self, arg1, arg2): """ 减法hook的实现""" print("do plugin2 hook") return arg1 - arg2
pm = pluggy.PluginManager("myproject") pm.add_hookspecs(MyHooks)
pm.register(Plugin1()) pm.register(Plugin2())
results = pm.hook.cal(arg1=1, arg2=2) print(results)
do plugin2 hook -1
|
传入了firstresult=True时,plugin的执行会在得到第一个非NONE的返回值的时候停下,不再往下执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import pluggy
hookspec = pluggy.HookspecMarker("myproject") hookimpl = pluggy.HookimplMarker("myproject")
class MyHooks: @hookspec(firstresult=True) def cal(self, arg1, arg2): """计算 hook 的声明"""
class Plugin1: @hookimpl() def cal(self, arg1, arg2): """ 加法hook的实现""" print("do plugin1 hook") return arg1 + arg2
class Plugin2: @hookimpl def cal(self, arg1, arg2): """ 减法hook的实现""" print("do plugin2 hook") return arg1 - arg2
class Plugin3: @hookimpl def cal(self, arg1, arg2): """ 减法hook的实现""" print("do plugin3 hook")
pm = pluggy.PluginManager("myproject") pm.add_hookspecs(MyHooks)
pm.register(Plugin1()) pm.register(Plugin2()) pm.register(Plugin3())
results = pm.hook.cal(arg1=1, arg2=2) print(results)
do plugin3 hook do plugin2 hook -1
|
pluggy 文档