如何为仅含静态函数的requests模块添加自定义请求结果检查函数?
嘿,我完全懂你遇到的困扰——想给requests.get()的结果加统一的复杂检查,一开始想着靠继承实现,结果发现requests.api只是个模块(不是类),根本没法继承对吧?别慌,咱们换个思路,下面这几个方案比直接继承更实用:
方案1:包装requests.get函数(最简单直接)
不用搞复杂的继承,直接写个自己的get函数,内部调用原生的requests.get,然后插入你的检查逻辑。其他程序直接用这个自定义函数就行,改动极小。
示例代码:
import requests def my_checked_get(url, **kwargs): # 调用原生requests.get response = requests.get(url, **kwargs) # 这里写你的复杂检查逻辑,举几个例子: # 1. 检查状态码,非200系列抛出异常 if not 200 <= response.status_code < 300: raise ValueError(f"请求失败,状态码:{response.status_code}") # 2. 如果预期响应是JSON,检查格式有效性 try: response.json() except ValueError: raise RuntimeError(f"URL {url} 返回的不是有效JSON") # 3. 检查响应内容里的特定字段(如果是JSON的话) if "required_field" not in response.json(): raise KeyError("响应JSON中缺少必填字段'required_field'") return response
用法:把原来代码里的requests.get()换成my_checked_get()就搞定了,完全兼容原生的参数(比如headers、params这些都能传)。
方案2:自定义Session类(适合需要会话管理的场景)
其实requests.get()底层是用了默认的Session实例来发送请求的。所以我们可以继承requests.Session,重写它的request方法(所有请求最终都会走这个方法),这样就能给所有请求(get/post/put等)统一加检查逻辑,还能保留Session的会话特性(比如自动维护cookies)。
示例代码:
import requests class CheckedSession(requests.Session): def request(self, method, url, **kwargs): # 调用父类的request方法获取响应 response = super().request(method, url, **kwargs) # 调用自定义的检查方法 self._validate_response(response, url) return response def _validate_response(self, response, url): # 这里集中写你的复杂检查逻辑 # 先利用requests自带的方法检查状态码 response.raise_for_status() # 自定义检查:比如响应内容长度符合要求 if len(response.content) < 100: raise RuntimeError(f"URL {url} 返回的内容过短,可能不完整") # 更多检查逻辑...
用法:
# 创建自定义Session实例 session = CheckedSession() # 所有通过这个session发送的请求都会自动执行检查 response = session.get("https://your-api-url.com/data") response_post = session.post("https://your-api-url.com/submit", data={"key": "value"})
方案3:使用装饰器(解耦检查逻辑)
把检查逻辑做成一个装饰器,这样可以灵活地给任何请求函数(包括原生的requests.get或者你自己写的函数)添加检查,实现逻辑复用。
示例代码:
import requests from functools import wraps def validate_response(func): @wraps(func) def wrapper(*args, **kwargs): response = func(*args, **kwargs) # 检查逻辑写这里 if response.status_code == 403: raise PermissionError("没有访问权限,请检查token") # 其他检查... return response return wrapper # 给原生requests.get加上检查 checked_get = validate_response(requests.get) # 直接使用装饰后的函数 response = checked_get("https://example.com/api")
这个方案的好处是,检查逻辑可以单独维护,还能随时给其他函数加上相同的检查,完全解耦。
补充:为什么继承requests.api不行?
你之前尝试的class Subclass(requests.api)无效,是因为requests.api是一个Python模块(对应api.py文件),而不是一个类。Python中只有类才能被继承,模块是不能作为父类的,所以这种写法肯定会报错。
内容的提问来源于stack exchange,提问作者BuffaloSpeedway

