python - 责任链模式实现(2)

ops/2024/11/14 1:35:31/

pluggy 是 Python 的一个插件管理库。pytest 利用 pluggy 实现插件化,在 Flask 或 Django 等 web 框架中,可以使用 pluggy 为 Middleware 或 View 功能扩展钩子。在数据流管道中,通过 pluggy 添加钩子实现数据采集、过滤、聚合等功能可用于处理数据流的不同阶段。

1. 创建过滤器接口

python">from pluggy import HookimplMarker
from pluggy import HookspecMarker
from pluggy import PluginManagerhookspec = HookspecMarker("example.filter")
hookimpl = HookimplMarker("example.filter")class FilterSpec:"""拦截器接口 ."""@hookspecdef process_request(self, request):pass@hookspecdef process_response(self, request, response):pass@hookspecdef process_view(self, request, view_func, view_args, view_kwargs):pass

FilterSpec 定义了一个插件的接口,其中每个用 @hookspec 装饰的函数可以理解为 hook 钩子 的接口声明。

2. 创建插件即过滤器的实现

python">
class FilterPlugin1:@hookimpldef process_request(self, request):request.data["result"].append("FilterPlugin1")@hookimpl(wrapper=True)def process_response(self, request, response):response.data["data"].append("FilterPlugin1 before yield")# 接受插件 FilterPlugin2 的返回结果results = yieldresults.append("FilterPlugin1")response.data["data"].append("FilterPlugin1 after yield")return resultsclass FilterPlugin2:@hookimpldef process_request(self, request):request.data["result"].append("FilterPlugin2")@hookimpl(wrapper=True)def process_response(self, request, response):response.data["data"].append("FilterPlugin2 before yield")# 接受插件 FilterPlugin3 的返回结果results = yieldresults.append("FilterPlugin2")response.data["data"].append("FilterPlugin2 after yield")return resultsclass FilterPlugin3:@hookimpldef process_request(self, request):request.data["result"].append("FilterPlugin3")@hookimpl(wrapper=True)def process_response(self, request, response):response.data["data"].append("FilterPlugin3 before yield")# 接受其他插件的执行结果results = yieldresults.append("FilterPlugin3")response.data["data"].append("FilterPlugin3 after yield")return results

@hookimpl 装饰器实现了 hook 钩子 的业务逻辑。

wrapper=True 可以使得 hook 可以接收其它插件的执行结果。

3. 注册插件

python"># 初始化 PluginManager
pm = PluginManager("example.filter")# 登记 hook 集合(hook函数声明)
pm.add_hookspecs(FilterSpec)# 注册插件(hook函数实现)
pm.register(FilterPlugin3()) # 第一个注册的插件最后执行
pm.register(FilterPlugin2())
pm.register(FilterPlugin1()) # 最后注册的插件最先执行class Request:def __init__(self):self.data = {"result": []}class Response:def __init__(self):self.data = {"code": 0,"data": [],"message": "",}

4. 单元测试

4.1 模拟请求中间件实现

python">def test_hook_request():# 调用两个插件类中的同名hook函数, 后注册的插件中的函数会先被调用request = Request()results = pm.hook.process_request(request=request)assert results == []  # 钩子实现返回 Noneassert request.data == {'result': ['FilterPlugin1', 'FilterPlugin2', 'FilterPlugin3']}

4.2 模拟响应中间件实现

python">def test_hook_response():request = Request()response = Response()results = pm.hook.process_response(request=request, response=response)assert results == ['FilterPlugin3', 'FilterPlugin2', 'FilterPlugin1']assert response.data == {'code': 0,'data': ['FilterPlugin1 before yield','FilterPlugin2 before yield','FilterPlugin3 before yield','FilterPlugin3 after yield','FilterPlugin2 after yield','FilterPlugin1 after yield',],'message': '',}

http://www.ppmy.cn/ops/94087.html

相关文章

鸿蒙开发APP应用UX体验标准

基础体验 应用导航 3.1.1.1 系统返回 页面布局 3.1.2.1 布局基础要求 3.1.2.2 挖孔区适配 人机交互 3.1.3.1 避免与系统手势冲突3.1.3.2 典型手势时长设计3.1.3.3 点击热区 视觉风格 3.1.4.1 色彩对比度3.1.4.2 字体大小 3.1.4.3 图标 3.1.4.3.1 应用图标3.1.4.3.2 界…

掌握图像处理中的颜色识别与形态学变换技术

形态学变换 形态学变换是一种基于形状的图像处理技术,主要应用于二值化图像。它的核心操作包括腐蚀和膨胀,这两者是对立的基本操作。 核(结构化元素):核是一个小的矩阵或模板,用于在图像上进行操作。它定义…

Python的反射以及应⽤用场景

Python中的反射(Reflection)是一种强大的机制,它允许程序在运行时(runtime)检查、修改其自身的结构和行为。这种机制通过内置的函数和模块实现,使得程序能够动态地访问对象的属性和方法。在Python中&#x…

WordPress原创插件:Keyword-ranking-seo 1.0 关键词排名插件 有利于seo

WordPress原创插件:Keyword-ranking-seo 1.0 关键词排名插件 有利于seo 当用户访问网站时,该链接会随机选择一个关键词,并使用选定的搜索引擎进行搜索。 插件下载链接 https://download.csdn.net/download/huayula/89632792

SpringBoot项目启动直接结束--已解决

点击启动类&#xff0c;项目启动了&#xff0c;但是却直接停止了。遇到这个问题如何解决呢&#xff1f; 想要项目一直启动是要部署在tomcat服务器上面了&#xff0c;说明现在项目没有运行在tomcat服务器上面。 解决方案: 添加springweb的starter依赖。 <dependency><…

第一篇:fiddler学习日记配置抓取https和http

Fiddler主要功能及实践 1、分析http请求/响应数据 2、设置断点&#xff0c;调试线上错误 3、设置档板服务器&#xff0c;自动返回各种响应 4、过滤会话&#xff0c;看自己想看的 案例&#xff1a; 1、分析http请求/响应数据 分析http协议请求和响应内容 查看登陆请求是否加密。…

ZK Rollup 的Sequencer

目录 ZK Rollup 的Sequencer 1. Sequence(Sequencer)的角色 2. Sequence的工作流程 3. Sequencer的重要性 4. 与其他角色的关系 ZK Rollup 的Sequencer 在ZK Rollup(也称为ZK Rollups)中,Sequence(或Sequencer)是一个关键的角色和过程,它对于实现高效的二层扩容…

[Qt][多元素控件]详细讲解

目录 0.前言1.List Widget2.Table Widget3.Tree Widget 0.前言 Qt中提供的多元素控件有&#xff1a; 列表&#xff1a; QListWidgetQListView 表格&#xff1a; QTableWidgetQTableView 树形&#xff1a; QTreeWidgetQTreeView Widget和View之间的区别&#xff0c;以QTableWi…