pytest 是基于 pluggy组织起来的,基于hook实现进行插件管理使得代码的模块设计非常灵活。
from pluggy import PluginManager, HookimplMarker, HookspecMarker
hookimpl = HookimplMarker("myhook")
hookspec = HookspecMarker("myhook")
class MyHook:
@hookspec
def func(self, a, b, c):
pass
class Plugin:
@hookimpl(tryfirst=True)
def func(self, a, b):
print(f"func:{b},{a}")
@hookimpl(hookwrapper=True)
def func_warp(self, a, b):
print(f"hookwrapper:{a},{b}")
yield a, b
# 后面的代码,所有的hookwrapper运行完毕后最后调用,调用顺序不受tryfirst 和trylask影响
print("yield 最后调用")
class PluginPlus:
@hookimpl(tryfirst=True)
def func(self, a, b):
print(f"PluginPlus:{b},{a}")
@hookimpl(hookwrapper=True, tryfirst=True)
def func_warp(self, a, b):
print(f"PluginPlus:{a},{b}")
yield a, b
print("PluginPlus yield 最后调用")
pm = PluginManager("myhook")
# 可以添加specs可以比添加。添加规范后,方法名相同参数不一致时会有警告;
pm.add_hookspecs(MyHook)
# 注册是定义plugin名称,成功返回名称,name已存在是报错
name = pm.register(Plugin(), "abc")
# 直接注册,名称为对象地址
pm.register(PluginPlus())
# 根据方法调用,会调用多个
pm.hook.func(a=1, b=2)
pm.hook.func_warp(a=1, b=2)
# 根据名称调用,精准调用一个
pm.get_plugin(name).func(a=1, b=2)
网友评论