howtopluggy

Example

import pluggy

hookspec = pluggy.HookspecMarker("myproject")  # 创建hooksepc 注解
hookimpl = pluggy.HookimplMarker("myproject")  # 创建hookimpl 注解

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) # 添加hook声明集合 也就是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

import pluggy

hookspec = pluggy.HookspecMarker("myproject")  # 创建hooksepc 注解
hookimpl = pluggy.HookimplMarker("myproject")  # 创建hookimpl 注解

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) # 添加hook声明集合 也就是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

import pluggy

hookspec = pluggy.HookspecMarker("myproject")  # 创建hooksepc 注解
hookimpl = pluggy.HookimplMarker("myproject")  # 创建hookimpl 注解
 
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) # 添加hook声明集合 也就是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

import pluggy

hookspec = pluggy.HookspecMarker("myproject")  # 创建hooksepc 注解
hookimpl = pluggy.HookimplMarker("myproject")  # 创建hookimpl 注解

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) # 添加hook声明集合 也就是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的返回值的时候停下,不再往下执行

import pluggy

hookspec = pluggy.HookspecMarker("myproject")  # 创建hooksepc 注解
hookimpl = pluggy.HookimplMarker("myproject")  # 创建hookimpl 注解

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) # 添加hook声明集合 也就是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 文档

posted @ 2025-02-02 22:35  且任荣枯  阅读(22)  评论(0)    收藏  举报