前言

  

什么是 pluggy

  pluggy 是 pytest 团队开发的库,
  用来解决给 pytest 写扩展插件的。
  pluggy 提供了方便的 API 可以很轻松的扩展框架的逻辑。

Github仓库
文档地址

pluggy 的调度方式

image

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


# create a manager and add the spec
pm = pluggy.PluginManager("myproject")
pm.add_hookspecs(MySpec)
# register plugins
pm.register(Plugin_1())
pm.register(Plugin_2())
# call our `myhook` hook
results = pm.hook.myhook(arg1=1, arg2=2)
print(results)

  代码来自官方文档
  执行会先触发 Plugin_2 再触发 Plugin_1

  上述是 pluggy 最简单的用法
  还有 firstresult hookwrapper 等用法
  可以参照文档说明学习,用法非常灵活。


  pm.hook.myhook 就是在源代码中的 代码桩。
  之前注册的插件都会在这个代码桩中逐一触发。
  pluggy 是可配置的,可以用代码动态地修改注册地插件,实时改变运行的逻辑。

总结

  使用 pluggy 可以将功能拆分成小文件

  1. 更好适配代码规范
  2. 逻辑更加简洁清晰,查找方便
  3. 功能扩展简单
  4. 启用禁用功能很方便