代码为例进行说明
实践环境
Python 3.6.5
pluggy 0.13.0
例1 注册类函数为插件函数
- #!/usr/bin/env python
- # -*- coding:utf-8 -*-
-
- import pluggy
-
- hookspec = pluggy.HookspecMarker("myproject") # hook 标签 用于标记hook
- hookimpl = pluggy.HookimplMarker("myproject") # hook 实现标签 用于标记hook的一个或多个实现
-
-
- class MySpec(object):
- """hook 集合"""
-
- @hookspec
- def myhook(self, arg1, arg2):
- pass
-
- @hookspec
- def my_hook_func1(self, arg1, arg2):
- pass
-
- @hookspec
- def my_hook_func2(self, arg1, arg2):
- pass
-
- # 插件类
- class Plugin_1(object):
- """hook实现类1"""
-
- @hookimpl
- def myhook(self, arg1, arg2):
- print("Plugin_1.myhook called")
- return arg1 + arg2
-
- @hookimpl
- def my_hook_func2(self, arg1, arg2):
- print("Plugin_1.my_hook_func2 called, args:", arg1, arg2)
-
- def my_hook_func3(self, arg1, arg2):
- print("Plugin_1.my_hook_func3 called, args:", arg1, arg2)
-
-
- class Plugin_2(object):
- """hook实现类2"""
-
- @hookimpl
- def myhook(self, arg1, arg2):
- print("Plugin_2.myhook called")
- return arg1 - arg2
-
- @hookimpl
- def my_hook_func2(self, arg1, arg2):
- print("Plugin_2.my_hook_func2, args:", arg1, arg2)
-
- # 初始化 PluginManager
- pm = pluggy.PluginManager("myproject")
-
- # 登记hook集合(hook函数声明)
- pm.add_hookspecs(MySpec)
-
- # 注册插件(hook函数实现)
- pm.register(Plugin_1())
- pm.register(Plugin_2())
-
- # 调用自定义hook
- results = pm.hook.myhook(arg1=1, arg2=2) # 调用两个插件类中的同名hook函数 # 后注册的插件中的函数会先被调用
- print(results) # 输出 [-1, 3]
-
- results = pm.hook.my_hook_func1(arg1="name", arg2="shouke")
- print(results)
-
- pm.hook.my_hook_func2(arg1="addr", arg2="sz")
-
运行结果
- Plugin_2.myhook called
- Plugin_1.myhook called
- [-1, 3]
- []
- Plugin_2.my_hook_func2, args: addr sz
- Plugin_1.my_hook_func2 called, args: addr sz
例2 注册模块函数为插件函数
myhookspec.py, myhookimpl.py, other.py, example.py位于同一包目录下
myhookspec.py
- import pluggy
-
- hookspec = pluggy.HookspecMarker("myproject") # hook 标签 用于标记hook
- hookimpl = pluggy.HookimplMarker("myproject") # hook 实现标签 用于标记hook的一个或多个实现
-
- @hookspec
- def global_hook_func1(arg1, arg2):
- pass
myhookimpl.py
- import pluggy
-
- from myhookspec import hookimpl
-
- @hookimpl
- def global_hook_func1(arg1, arg2):
- print("global_hook_func1 in myhookimpl.py, args:", arg1, arg2)
- return "myhookimpl.py"
other.py
- from myhookspec import hookimpl
-
- @hookimpl
- def global_hook_func1(arg1, arg2):
- print("global_hook_func1 in other.py, args:", arg1, arg2)
- return "other.py"
example.py
- #!/usr/bin/env python
- # -*- coding:utf-8 -*-
-
- import sys
- import pluggy
- import myhookspec
- import myhookimpl
- import other
-
- # 初始化 PluginManager
- pm = pluggy.PluginManager("myproject")
-
- # 登记hook集合
- pm.add_hookspecs(myhookspec)
-
- # 登记hook的实现
- pm.register(myhookimpl) # 插件也可以是模块
- pm.register(other)
-
- print(pm.hook.global_hook_func1(arg1="name", arg2="shouke"))
example.py运行结Python基础教程果如下
- global_hook_func1 in other.py, args: name shouke
- global_hook_func1 in myhookimpl.py, args: name shouke
- ['other.py', 'myhookimpl.py']
例3:自定义插件类实现hook函数免@hookimpl装饰器
myhookspec.py
- import pluggy
-
- hookspec = pluggy.HookspecMarker("myproject")
-
- @hookspec
- def mytest_hook_func1(arg1, arg2):
- pass
other.py
- def mytest_hook_func1(arg1, arg2):
- print("global_hook_func1 in other.py, args:", arg1, arg2)
- return "other.py"
example.py
- #!/usr/bin/env python
- # -*- coding:utf-8 -*-
-
- import inspect
- import pluggy
- import myhookspec
- import other
-
-
- class PytestPluginManager(pluggy.PluginManager):
- """
- 插件类,实现不用@HookimplMarkerInstance装饰的函数也可以当做函数体
- """
-
- def parse_hookimpl_opts(self, plugin, name):
- # 规定免@hookimpl装饰的 hooks 函数总是以 mytest_打头,这样以避免访问非可读属性
-
- if not name.startswith("mytest_"):
- return
-
- method = getattr(plugin, name)
- opts = super().parse_hookimpl_opts(plugin, name)
-
- # 考虑hook只能为函数(consider only actual functions for hooks)
- if not inspect.isroutine(method):
- return
-
- # 收集未被标记的,以mytest打头的hook函数,(collect unmarked hooks as long as they have the `pytest_' prefix)
- if opts is None and name.startswith("mytest_"):
- opts = {}
- return opts
-
-
- # 初始化 PluginManager
- pm = PytestPluginManager("myproject")
-
- # 登记hook集合
- pm.add_hookspecs(myhookspec)
-
- # 登记hook的实现
- pm.register(other)
-
- pm.hook.mytest_hook_func1(arg1="addr", arg2="sz")
参考连接
https://pypi.org/project/pluggy/
作者:授客
本文版权归原作者所有,仅供学习参考之用,转载请注明出处:https://www.cnblogs.com/shouke/p/14940707.html,未经作者允许请务必保留此段声明!




















