关键词搜索

源码搜索 ×
×

Python pluggy框架基础用法总结

发布2021-06-30浏览474次

详情内容

代码为例进行说明

实践环境

Python 3.6.5

pluggy 0.13.0

例1 注册类函数为插件函数

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import pluggy
  4. hookspec = pluggy.HookspecMarker("myproject") # hook 标签 用于标记hook
  5. hookimpl = pluggy.HookimplMarker("myproject") # hook 实现标签 用于标记hook的一个或多个实现
  6. class MySpec(object):
  7. """hook 集合"""
  8. @hookspec
  9. def myhook(self, arg1, arg2):
  10. pass
  11. @hookspec
  12. def my_hook_func1(self, arg1, arg2):
  13. pass
  14. @hookspec
  15. def my_hook_func2(self, arg1, arg2):
  16. pass
  17. # 插件类
  18. class Plugin_1(object):
  19. """hook实现类1"""
  20. @hookimpl
  21. def myhook(self, arg1, arg2):
  22. print("Plugin_1.myhook called")
  23. return arg1 + arg2
  24. @hookimpl
  25. def my_hook_func2(self, arg1, arg2):
  26. print("Plugin_1.my_hook_func2 called, args:", arg1, arg2)
  27. def my_hook_func3(self, arg1, arg2):
  28. print("Plugin_1.my_hook_func3 called, args:", arg1, arg2)
  29. class Plugin_2(object):
  30. """hook实现类2"""
  31. @hookimpl
  32. def myhook(self, arg1, arg2):
  33. print("Plugin_2.myhook called")
  34. return arg1 - arg2
  35. @hookimpl
  36. def my_hook_func2(self, arg1, arg2):
  37. print("Plugin_2.my_hook_func2, args:", arg1, arg2)
  38. # 初始化 PluginManager
  39. pm = pluggy.PluginManager("myproject")
  40. # 登记hook集合(hook函数声明)
  41. pm.add_hookspecs(MySpec)
  42. # 注册插件(hook函数实现)
  43. pm.register(Plugin_1())
  44. pm.register(Plugin_2())
  45. # 调用自定义hook
  46. results = pm.hook.myhook(arg1=1, arg2=2) # 调用两个插件类中的同名hook函数 # 后注册的插件中的函数会先被调用
  47. print(results) # 输出 [-1, 3]
  48. results = pm.hook.my_hook_func1(arg1="name", arg2="shouke")
  49. print(results)
  50. pm.hook.my_hook_func2(arg1="addr", arg2="sz")

运行结果

  1. Plugin_2.myhook called
  2. Plugin_1.myhook called
  3. [-1, 3]
  4. []
  5. Plugin_2.my_hook_func2, args: addr sz
  6. Plugin_1.my_hook_func2 called, args: addr sz

例2 注册模块函数为插件函数

myhookspec.py, myhookimpl.py, other.py, example.py位于同一包目录下

myhookspec.py

  1. import pluggy
  2. hookspec = pluggy.HookspecMarker("myproject") # hook 标签 用于标记hook
  3. hookimpl = pluggy.HookimplMarker("myproject") # hook 实现标签 用于标记hook的一个或多个实现
  4. @hookspec
  5. def global_hook_func1(arg1, arg2):
  6. pass

myhookimpl.py

  1. import pluggy
  2. from myhookspec import hookimpl
  3. @hookimpl
  4. def global_hook_func1(arg1, arg2):
  5. print("global_hook_func1 in myhookimpl.py, args:", arg1, arg2)
  6. return "myhookimpl.py"

other.py

  1. from myhookspec import hookimpl
  2. @hookimpl
  3. def global_hook_func1(arg1, arg2):
  4. print("global_hook_func1 in other.py, args:", arg1, arg2)
  5. return "other.py"

example.py

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import sys
  4. import pluggy
  5. import myhookspec
  6. import myhookimpl
  7. import other
  8. # 初始化 PluginManager
  9. pm = pluggy.PluginManager("myproject")
  10. # 登记hook集合
  11. pm.add_hookspecs(myhookspec)
  12. # 登记hook的实现
  13. pm.register(myhookimpl) # 插件也可以是模块
  14. pm.register(other)
  15. print(pm.hook.global_hook_func1(arg1="name", arg2="shouke"))

example.py运行结Python基础教程果如下

  1. global_hook_func1 in other.py, args: name shouke
  2. global_hook_func1 in myhookimpl.py, args: name shouke
  3. ['other.py', 'myhookimpl.py']

例3:自定义插件类实现hook函数免@hookimpl装饰器

myhookspec.py

  1. import pluggy
  2. hookspec = pluggy.HookspecMarker("myproject")
  3. @hookspec
  4. def mytest_hook_func1(arg1, arg2):
  5. pass

other.py

  1. def mytest_hook_func1(arg1, arg2):
  2. print("global_hook_func1 in other.py, args:", arg1, arg2)
  3. return "other.py"

example.py

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import inspect
  4. import pluggy
  5. import myhookspec
  6. import other
  7. class PytestPluginManager(pluggy.PluginManager):
  8. """
  9. 插件类,实现不用@HookimplMarkerInstance装饰的函数也可以当做函数体
  10. """
  11. def parse_hookimpl_opts(self, plugin, name):
  12. # 规定免@hookimpl装饰的 hooks 函数总是以 mytest_打头,这样以避免访问非可读属性
  13. if not name.startswith("mytest_"):
  14. return
  15. method = getattr(plugin, name)
  16. opts = super().parse_hookimpl_opts(plugin, name)
  17. # 考虑hook只能为函数(consider only actual functions for hooks)
  18. if not inspect.isroutine(method):
  19. return
  20. # 收集未被标记的,以mytest打头的hook函数,(collect unmarked hooks as long as they have the `pytest_' prefix)
  21. if opts is None and name.startswith("mytest_"):
  22. opts = {}
  23. return opts
  24. # 初始化 PluginManager
  25. pm = PytestPluginManager("myproject")
  26. # 登记hook集合
  27. pm.add_hookspecs(myhookspec)
  28. # 登记hook的实现
  29. pm.register(other)
  30. pm.hook.mytest_hook_func1(arg1="addr", arg2="sz")

参考连接

https://pypi.org/project/pluggy/

作者:授客
本文版权归原作者所有,仅供学习参考之用,转载请注明出处:https://www.cnblogs.com/shouke/p/14940707.html,未经作者允许请务必保留此段声明!

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载