Python中的钩子函数(hooks)介绍使用

什么是hook?

钩子函数,顾名思义,就是把我们自己实现的自定义函数在某一时刻挂接到目标挂载点上去执行。
1. hook函数,就是我们自己实现的函数,函数类型与挂载点匹配(返回值,参数列表)
2. 挂接,也就是hook或者叫注册(register),使得hook函数对目标可用
3. 目标挂载点,也就是挂我们hook函数的地方(我们想在这个目标点实现我们自己的功能)

hook是一种编程机制,与具体的编程语言无关。

为什么需要hook?

什么情况下需要实现hook?
—就是一个功能(类/方法)自身无法满足所有需求,那么可以通过hook 就提供扩展自身能力的可能

同一个需求平替实现

比如有个需求:获取每次请求后的请求状态码

方式1:原始做法直接在代码里增加

–不推荐,而且违反“开闭原则”

import requests
url = ' http://www.baidu.com'
r = requests.get(url)
print(f"status doce: {r.status_code}")

方式2:使用装饰器

import requests
# 定义装饰器
def print_status_code(func):
    def wrappers(*args, **kwargs):
        res = func(*args, **kwargs)
        print(f"Status code: {res.status_code}")
        return res
    return wrappers
@print_status_code
def send_request(url):
    res = requests.get(url)
    return res

url='https://httpbin.org/get'
send_request(url)

方式3:使用requests库自动hooks入参来使用钩子函数:将“获取请求状态的逻辑封装到一个函数中,在执行完请求后,就自动执行钩子函数"

import requests	没有参数
def custom_hooks(response,**kwargs):
	print(response.status_code)
def custom_hooks2(response,**kwargs):
	print(response.headers)
url = ' http://www.baidu.com'
response = requests.get(url, hooks={"response": [custom_hooks, custom_hooks2]})

钩子函数什么时候执行?

比如:response = requests.get(url, hooks={“response”: [custom_hooks, custom_hooks2]})
自定义的钩子函数在执行完请求后,执行钩子函数

实例:requests库的hooks介绍

requests提供了hook机制,让我们能够在请求得到响应之后,再去额外做一些自定义的操作,比如打印某些信息、修改响应内容等。

注意:

  1. requests库中钩子函数是在请求得到响应之后才去行的钩子函数
  2. 如下示例测试数据基于requests 2.25.1

requests库如何使用hooks来调用钩子函数?

import requests
# 钩子函数1
def print_url(r, **kwargs):
	print("raw_url "+r.url)
# 钩子函数2
def change_url(r, **kwargs):
	r.url = ' http://change.url'
	print("changed_url "+r.url)
	return r  # 其实没有这句话,也可以修改r.url,因为r是response对象而非普通数值,但requests官方似乎误认为回调函数一定要有return才能替换传入的数据
url = ' http://httpbin.org/cookies'
# 使用hooks形参来调用钩子函数
response = requests.get(url, hooks=dict(response=[print_url, change_url]))
print("result_url "+response.url)

注意:
1) 钩子函数中的**kwargs形参不能少,且必须是关键字参数
□ 因为在调用钩子函数时,requests.session.py实现了添加了相关参数 在这里插入图片描述2) requests.中的hook入参值类型必须是字典,且key必须是"response",value有多个时必须为list类型。
□ key必须是"response": 因为
①requests.hooks.py如下代码有校验
在这里插入图片描述
②requests.models.py有如下校验 在这里插入图片描述

requests库使用钩子函数时,如果钩子函数需要传递参数,如何向钩子函数传递参数?

有两种方式:
方式1: 使用偏函数(funtools.partial)过要注意,使用这种方式,不能适用于钩子函数有多个位置参数的情况,只适配与钩子函数有关键字参数的情况。所以要将钩子函数设计成def my_hook_func(response, **kwargs)这种形式。
因为当使用 functools.partial 结合 requests 库的钩子函数时,直接传递位置参数会干扰 requests 默认传递给钩子函数的参数顺序。 requests 库在调用钩子函数时,会将 response 对象作为第一个参数传入。如果使用 partial 传递位置参数,这些位置参数会占用钩子函数本来为 response 留下的位置,从而导致错误。
示例:

import requests
from functools import partial

# 定义钩子函数
def response_hook(response, **kwargs):
	print(f"所有关键字参数{kwargs}")
	parms1 = kwargs.get('parms1')
	parms2 = kwargs.get('parms2')
	print("额外参数2:", parms1)
	print("额外参数2:", parms2)
	print("响应状态码:", response.status_code)
	return response

# 使用 partial 来创建一个新的钩子函数,其中传入了关键字参数
hook_with_param = partial(response_hook, parms1='val1', parms2='val2')

# 进行请求,并传入钩子函数
response = requests.get('https://httpbin.org/get', hooks={'response': hook_with_param})

# 打印响应内容
print(response.text)

方式2:使用闭包
使用闭包比使用偏函数稍微麻烦一点,不过使用闭包能支持位置参数和关键字参数,这点要比偏函数好

import requests

# 定义一个外层函数来包裹钩子函数,从而传入额外的参数
def create_response_hook(extra_param, additional_arg, **kwargs2):
	def response_hook(response, *args, **kwargs):
		print(f"kwargs参数的值{kwargs}")
		print("响应状态码:", response.status_code)
		print("额外参数:", extra_param)
		print("额外位置参数:", additional_arg)
		print("额外关键字参数:", kwargs2)
		print("params1参数:", kwargs2.get("params1"))
		print("params2参数:", kwargs2.get("params2"))
		return response
	return response_hook

# 创建带有额外参数的钩子函数
hook_with_param = create_response_hook('额外的数据', '额外位置参数1', params1="val1", params2="val2")

# 进行请求,并传入钩子函数
response = requests.get('https://httpbin.org/get', hooks={'response': hook_with_param})

# 打印响应内容
print(response.text)


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/700268.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Fake news detection: A survey of graph neural network methods

abstract 各种社交网络的出现产生了大量的数据。捕获、区分和过滤真假新闻的有效方法变得越来越重要,特别是在 COVID-19 大流行爆发之后。本研究对假新闻检测系统的图神经网络 (GNN) 的现状和挑战进行了多方面、系统的回顾,并概述了使用 GNN 实现假新闻…

C++STL初阶(4):初识vector

vector是一个类模版,是一个顺序容器,底层思维就是顺序表,而顺序表的本质就是一个可以改变size的数组。本篇基于string的学习基础,我们对vector进行一个大致的了解和学习 1.基本介绍 1. vector 是表示可变大小数组的序列容器&#…

老生常谈!程序员为什么要阅读源代码?

大家好,我是码农先森。 阅读源码这是一个老生常谈的话题了,但又是很多人想做又没有付出行动的事情。前段时间我研究了 Swoole 的源代码,并且输出了系列的源码分析文章「感兴趣的朋友可以翻阅以前的文章」。虽然这个过程很枯燥和艰难&#xf…

css font-family

知乎的font-family的设置理解 -apple-system, BlinkMacSystemFont 这两个值是为了确保在macOS和iOS系统上能够使用系统默认字体进行文本渲染。-apple-system特别为Safari浏览器设计,而BlinkMacSystemFont则主要针对基于Chromium的浏览器(如Chrome&#…

【Linux】shell——条件判断test,各种运算符,expr

条件判断——test 真——0 假——1 test expression or [ expression ] 整数运算符 字符串运算符 -z 长度是否为0 -n 长度是否不为0 str1 str2 str1 ! str2 补 &&-->逻辑与,前面为真后面才会执行 || -->逻辑或,前面为假后面才…

京东网页html+css简单制作1(附带源码和素材)

一.代码效果展示 代码html骨架结构分为头部top,颈部banner,中间部分main,腿部fortet-image,尾部fortter,五部分组成,从上至下,从左到右结构。(总体因为没设计版心,所以位置比较乱) 其中中部mai…

云动态摘要 2024-06-11

给您带来云厂商的最新动态,最新产品资讯和最新优惠更新。 最新优惠与活动 [低至1折]腾讯混元大模型产品特惠 腾讯云 2024-06-06 腾讯混元大模型产品特惠,新用户1折起! 云服务器ECS试用产品续用 阿里云 2024-04-14 云服务器ECS试用产品续用 最新产品更新 云服务器运维监…

设计模式-代理模式(结构型)

代理模式 代理模式是一种结构型模式,它可以通过一个类代理另一个类的功能。代理类持有被代理类的引用地址,负责将请求转发给代理类,并且可以在转发前后做一些处理 图解 角色 抽象主题(Subject): 定义代理对象和被代理…

【安卓13 源码】Input子系统(2) - input系统与应用进程通信

点击手机屏幕,可以分发input 事件到对应的view,由上一节知道input 是运行在system 进程的,那应用进程与系统进程是如何通讯的呢,相信本文可以给到一点小小的答案。 先给个结论:应用在resume 的时候才去建立与input 服…

项目部署(前后端)

一:多环境概念: 借鉴来源:多环境设计_程序员鱼皮-多环境设计-CSDN博客 为什么需要多环境: 第一个例子:我们可以设想,我们肯定玩过王者荣耀,且王者荣耀也一直在不断更新,如果按我们…

cleanmymac清理时要一直输入密码 CleanMyMac X一直提示输入密码的解决方案

CleanMyMac X是一款专业的Mac清理软件,可智能清理mac磁盘垃圾和多余语言安装包,快速释放电脑内存,轻松管理和升级Mac上的应用。同时CleanMyMac X可以强力卸载恶意软件,修复系统漏洞,一键扫描和优化Mac系统。 在使用Cle…

【人工智能基础学习】Andrew Ng-机器学习基础笔记

⭐️我叫忆_恒心,一名喜欢书写博客的研究生👨‍🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支…

HyperSnap软件最新版下载-HyperSnap官方最新版附加详细安装步骤

​HyperSnap是一个老牌优秀的屏幕截图工具,全新界面,不仅能抓取标准桌面程序,还能抓取 DirectX, 3Dfx Glide的 游戏视频或 DVD 屏幕图,能以 20 多种图形格式(包括:BMP, GIF,JPEG, TIFF, PCX等)保…

鸿蒙开发:应用组件跨设备交互(流转)【跨端迁移】

跨端迁移 概述 在用户使用设备的过程中,当使用情境发生变化时(例如从室内走到户外或者周围有更适合的设备等),之前使用的设备可能已经不适合继续当前的任务,此时,用户可以选择新的设备来继续当前的任务&a…

C盘爆满?教你轻松清理无故产生的大量临时文件!

在电脑操作中,用户发现自己系统C盘爆满了,无缘无故产生了大量的临时文件,导致电脑运作变得卡顿,但不知道要怎么操作才能解决这个问题?接下来小编给小伙伴们带来不同的解决方法,轻松清理电脑上的临时文件。 …

【lesson7】服务端业务处理模块实现

文章目录 业务处理实现思路业务处理类设计成员变量成员函数RunModuleupLoadlistShowdownLoadgetETagInfo 业务处理实现思路 云备份项目中 ,业务处理模块是针对客户端的业务请求进行处理,并最终给与响应。而整个过程中包含以下要实现的功能: …

这所大学25考研计算机学院专业课已全面改考为408!南京信息工程大学计算机考研!

南京信息工程大学(Nanjing University of Information Science and Technology),简称“南信大”,位于江苏省南京市,是一所以大气科学为特色的全国重点大学,由江苏省人民政府、中华人民共和国教育部、中国气…

【lesson1】第三方库(jsoncpp,bundle, httplib)的介绍和使用

文章目录 jsoncpp库json 认识jsoncpp 认识jsoncpp 实现序列化jsoncpp 实现反序列化 bundle库bundle库实现文件压缩bundle库实现文件解压缩 httplib 库httplib 库搭建简单服务器httplib库搭建简单客户端 jsoncpp库 json 认识 json 是一种数据交换格式,采用完全独立…

OS进程取样器OS Process Sampler执行CMD/Shell命令

Apache JMeter - Users Manual: Component Reference 1.背景 项目上最近需要测试一种很少用到的DICOM协议,但是网上资料很少,基本上可以总结为三种方案: 直接发送TCP 16进制数据包,但是参数化数据准备难度大通过开发封装jar包发送,需要开发组提供通过发送cmd命令给前置机…

ES升级--05--快照生成 和备份

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 备份ES数据1.关闭集群自动均衡2.执行同步刷新3.停止集群节点的Elasticsearch服务4.修改Elasticsearch配置文件,开启快照功能,配置仓库目录为…