前言
什么是 pluggy
pluggy 是 pytest 团队开发的库,
用来解决给 pytest 写扩展插件的。
pluggy 提供了方便的 API 可以很轻松的扩展框架的逻辑。
Github仓库
文档地址
pluggy 的调度方式

draw.io链接
pluggy 有三大要素
HookspecMarker
(hookspec) 定义
HookimplMarker
(hookimpl) 实现
PluginManager
(pm) 插件管理器
spec 定义了可以暴露的方法,可以通过 pm.hook 去调用对应的方法
调用的时候会逐个执行 impl 注册的插件,按 LIFO 后进先出的方式进行。
pluggy 案例代码
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
| import pluggy
hookspec = pluggy.HookspecMarker("myproject") hookimpl = pluggy.HookimplMarker("myproject")
class MySpec: """A hook specification namespace."""
@hookspec def myhook(self, arg1, arg2): """My special little hook that you can customize."""
class Plugin_1: """A hook implementation namespace."""
@hookimpl def myhook(self, arg1, arg2): print("inside Plugin_1.myhook()") return arg1 + arg2
class Plugin_2: """A 2nd hook implementation namespace."""
@hookimpl def myhook(self, arg1, arg2): print("inside Plugin_2.myhook()") return arg1 - arg2
pm = pluggy.PluginManager("myproject") pm.add_hookspecs(MySpec)
pm.register(Plugin_1()) pm.register(Plugin_2())
results = pm.hook.myhook(arg1=1, arg2=2) print(results)
|
代码来自官方文档
执行会先触发 Plugin_2
再触发 Plugin_1
上述是 pluggy 最简单的用法
还有 firstresult
hookwrapper
等用法
可以参照文档说明学习,用法非常灵活。
pm.hook.myhook
就是在源代码中的 代码桩。
之前注册的插件都会在这个代码桩中逐一触发。
pluggy 是可配置的,可以用代码动态地修改注册地插件,实时改变运行的逻辑。
总结
使用 pluggy 可以将功能拆分成小文件
- 更好适配代码规范
- 逻辑更加简洁清晰,查找方便
- 功能扩展简单
- 启用禁用功能很方便