代码为例进行说明

实践环境

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框架基础用法总结的更多相关文章

  1. Python Numpy shape 基础用法(转自他人的博客,如涉及到侵权,请联系我)

    Python Numpy shape 基础用法 shape函数是numpy.core.fromnumeric中的函数,它的功能是读取矩阵的长度,比如shape[0]就是读取矩阵第一维度的长度.它的输入 ...

  2. Python学习---Python的框架基础学习

    框架基础 框架实质: 所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端 B/S结构的响应: import socket def handle_requ ...

  3. python内建函数isinstance基础用法

      语法:isinstance(object,type) 作用:来判断一个对象是否是一个已知的类型.  其第一个参数(object)为对象,第二个参数(type)为类型名(int...)或类型名的一个 ...

  4. python bottle框架(WEB开发、运维开发)教程

    教程目录 一:python基础(略,基础还是自己看书学吧) 二:bottle基础 python bottle web框架简介 python bottle 框架环境安装 python bottle 框架 ...

  5. Python云端系统开发入门——框架基础

    Django框架基础 这是我学习北京理工大学嵩天老师的<Python云端系统开发入门>课程的笔记,在此我特别感谢老师的精彩讲解和对我的引导. 1.Django简介与安装 Django是一个 ...

  6. 【Python爬虫】selenium基础用法

    selenium 基础用法 阅读目录 初识selenium 基本使用 查找元素 元素互交操作 执行JavaScript 获取元素信息 等待 前进后退 Cookies 选项卡管理 异常处理 初识sele ...

  7. Python web框架 Tornado(一)基础学习

    概述 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了 ...

  8. 零基础小白必看篇:从0到1构建Python Web框架

    造轮子是最好的一种学习方式,本文尝试从0开始造个Python Web框架的轮子,我称它为ToyWebF. 本文操作环境为:MacOS,文中涉及的命令,请根据自己的系统进行替换. ToyWebF的简单特 ...

  9. Python测试框架pytest入门基础

    Pytest简介 Pytest is a mature full-featured Python testing tool that helps you write better programs.T ...

  10. 爬虫之Scrapy框架介绍及基础用法

    今日内容概要 爬虫框架之Scrapy 利用该框架爬取博客园 并发编程 今日内容详细 爬虫框架Scrapy 1.什么是框架? 框架类似于房子的结构,框架会提前帮你创建好所有的文件和内部环境 你只需要往对 ...

随机推荐

  1. 透过 Go 语言探索 Linux 网络通信的本质

    前言 各种编程语言百花齐放.百家争鸣,但是 "万变不离其中".对于网络通信而言,每一种编程语言的实现方式都不一样:但其实,调用的底层逻辑都是一样的.linux 系统底层向上提供了统 ...

  2. pymysql的基本操作

    1.Python3连接MySQL import pymysql pymysql.connect(host='localhost',user='root',password='1',database=' ...

  3. H.265码流解析

    这一篇内容旨在对H.265码流中的一些概念做简单了解,部分概念与H.264相同,本篇中将不再重复. 1.NALU H.265(HEVC)码流的NALU结构和AVC有一些不同,属于增强版,HEVC NA ...

  4. 分享一个关于Avl树的迭代器算法

    1 研究过程 前段时间在研究avl树的迭代实现,在节点不使用parent指针的情况下,如何使用堆栈来实现双向地迭代.我参考了网络上的大部分迭代器实现,要么是使用了parent指针(就像c++的map容 ...

  5. NOIP模拟59

    T1 柱状图 解题思路 二分答案+线段树check 显然对于最后的限制,我们希望向上移的和向下移的柱子数尽量接近. 因此枚举每一个柱子当做最高的一个的时刻,二分找到一个当前最优解更新答案. 开两棵线段 ...

  6. react做购物车的功能

    父组件 import React, { Component } from 'react' import Lists from '../components/Lists' export default ...

  7. webpack配置css预处理

    webpack默认只支持js的打包,不支持其它类型,为了让它支持样式的打包就需要加载一些loader 打包css文件 在webpack中配置对应的loader 在入口js文件中通过import导入样式 ...

  8. UDP 发送两遍对比一致能绝对判定发送过程成功传递完整数据吗

    UDP 发送两边对比一致,能确定数据传输无错误吗 对比两条相同数据的MD5 这样做可行吗

  9. bili-emoji自定义表情包设置

    使用图床上传图片.推荐使用聚合图床,简单免费 把图片的图床链接复制到一个txt文件中,如abc.txt 将abc.txt放到koishi目录的非node_modules\koishi-plugin-e ...

  10. Java POI 生成Word文档

    maven的pom <dependency> <groupId>org.apache.poi</groupId> <artifactId>ooxml-s ...