Python pluggy框架使用示例代码

目录
  • 实践环境
  • 例1 注册类函数为插件函数
  • 例2 注册模块函数为插件函数
    • myhookspec.py
    • myhookimpl.py
    • other.py
    • example.py
  • 例3:自定义插件类实现hook函数免@hookimpl装饰器
    • myhookspec.py
    • other.py
    • example.py
  • 参考连接

代码为例进行说明

实践环境

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.pymyhookimpl.pyother.pyexample.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/

到此这篇关于Python pluggy框架基础用法总结的文章就介绍到这了,更多相关Python pluggy用法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2022-05-12

Python pluggy模块的用法示例演示

目录 1 pluggy 简介 2 安装 3 使用初体验 4 详解解释 5 HookspeckMarker装饰器支持传入一些特定的参数 6 HookImplMarker装饰器也支持传入一些特定的参数 1 pluggy 简介 pluggy 作用:提供了一个简易便捷的插件系统,可以做到插件与主题功能松耦合 pluggy 是pytest,tox,devpi的核心框架 2 安装 执行如下命令即可 pip install pluggy 3 使用初体验 import pluggy # HookspecMark

Python统计分析模块statistics用法示例

本文实例讲述了Python统计分析模块statistics用法.分享给大家供大家参考,具体如下: 一 计算平均数函数mean() >>>import statistics >>> statistics.mean([1,2,3,4,5,6,7,8,9])#使用整数列表做参数 5 >>> statistics.mean(range(1,10))#使用range对象做参数 5 >>>import fractions >>>

Python多线程模块Threading用法示例小结

本文实例讲述了Python多线程模块Threading用法.分享给大家供大家参考,具体如下: 步入正题前,先准备下基本知识,线程与进程的概念. 相信作为一个测试人员,如果从理论概念上来说其两者的概念或者区别,估计只会一脸蒙蔽,这里就举个例子来说明下其中的相关概念. 平安夜刚过,你是吃到了苹果还是香蕉呢...其实当你用手去接下对方苹果的时候,你的手臂就可以比喻成进程,你的五个手指就可以比喻成线程,所以很明显,线程可以说是进程的细化,没有进程就不会有线程. 这里还是说下必要的概念:    进程 是操

Python subprocess模块常见用法分析

本文实例讲述了Python subprocess模块常见用法.分享给大家供大家参考,具体如下: subprocess模块是python从2.4版本开始引入的模块.主要用来取代 一些旧的模块方法,如os.system.os.spawn*.os.popen*.commands.*等.subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息. 常用方法: subprocess.call():执行命令,并返回执行状态,其中shell参数为F

Python数据分析模块pandas用法详解

本文实例讲述了Python数据分析模块pandas用法.分享给大家供大家参考,具体如下: 一 介绍 pandas(Python Data Analysis Library)是基于numpy的数据分析模块,提供了大量标准数据模型和高效操作大型数据集所需要的工具,可以说pandas是使得Python能够成为高效且强大的数据分析环境的重要因素之一. pandas主要提供了3种数据结构: 1)Series,带标签的一维数组. 2)DataFrame,带标签且大小可变的二维表格结构. 3)Panel,带标

Python图像处理模块ndimage用法实例分析

本文实例讲述了Python图像处理模块ndimage用法.分享给大家供大家参考,具体如下: 一 原始图像 1 代码 from scipy import misc from scipy import ndimage import matplotlib.pyplot as plt face = misc.face()#face是测试图像之一 plt.figure()#创建图形 plt.imshow(face)#绘制测试图像 plt.show()#原始图像 2 运行结果 二 高斯滤波 1 代码 fro

Python异常模块traceback用法实例分析

本文实例讲述了Python异常模块traceback用法.分享给大家供大家参考,具体如下: traceback模块被用来跟踪异常返回信息. 如下例所示: import traceback try: raise SyntaxError, "traceback test" except: traceback.print_exc() 将会在控制台输出类似结果: Traceback (most recent call last):   File "H:PythonWorkSpaceT

Python random模块的使用示例

常用的 random 模块方法 import random # random.random()用于生成一个 0 到 1 的随机浮点数: 0 <= n < 1.0 print(random.random()) # 0.18246795790915304 # random.randint(a, b),用于生成一个指定范围内的整数. # 其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b print(random.randint(1, 10)) # 8 # rand

Python ConfigParser模块的使用示例

前言 在做项目的时候一些配置文件都会写在settings配置文件中,今天在研究"州的先生"开源文档写作系统-MrDoc的时候,发现部分配置文件写在config.ini中,并利用configparser进行相关配置文件的读取及修改. 一.ConfigParser模块简介 该模块适用于配置文件的格式与windows ini文件类似,是用来读取配置文件的包.配置文件的格式如下:中括号"[ ]"内包含的为section.section 下面为类似于key-value 的配置

Python切片工具pillow用法示例

本文实例讲述了Python切片工具pillow用法.分享给大家供大家参考,具体如下: 切片:使用切片将源图像分成许多的功能区域 因为要对图片进行切片裁剪,所以用到切片工具必不可少,在ubuntu下有很多的图片处理工具,如 GIMP(Ubuntu的下的Photoshop),shotwell,shotter等等. 但是我想吧一张图片剪裁下来,用那些工具不怎么方便(其实可能是我没有找到而已),于是上网搜索资料,发现各式各类的工具,其中发现了pollow这款工具. 算是Python下的一个模块吧,这个模

Python paramiko模块的使用示例

paramiko模块提供了ssh及sft进行远程登录服务器执行命令和上传下载文件的功能.这是一个第三方的软件包,使用之前需要安装. 1 基于用户名和密码的 sshclient 方式登录 # 建立一个sshclient对象 ssh = paramiko.SSHClient() # 允许将信任的主机自动加入到host_allow 列表,此方法必须放在connect方法的前面 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 调用c