百木园-与人分享,
就是让自己快乐。

Python pluggy框架基础用法总结

代码为例进行说明

实践环境

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运行结果如下

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
图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » Python pluggy框架基础用法总结

相关推荐

  • 暂无文章