You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为调用requests.get的Python函数添加自定义装饰器?

实现方案:用装饰器临时替换requests.get

核心思路是在被装饰函数执行的生命周期内,临时替换requests.get为预先包装好的版本,执行完函数后立刻恢复原方法——这样既不用修改任何现有requests.get调用,也不会影响全局范围内的requests.get使用。

具体实现

基础版装饰器

import requests
from functools import wraps

def my_custom_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 保存原始的requests.get方法
        original_get = requests.get
        
        # 定义包装后的get方法,添加通用参数
        def wrapped_get(url, **get_kwargs):
            # 这里可以定义你需要的通用参数
            default_params = {
                "timeout": 15,
                "headers": {"User-Agent": "CustomBot/1.0"},
                "verify": False  # 示例:关闭SSL验证(根据需求调整)
            }
            # 用户传入的参数会覆盖默认值,保证灵活性
            merged_kwargs = {**default_params, **get_kwargs}
            return original_get(url, **merged_kwargs)
        
        # 替换requests.get
        requests.get = wrapped_get
        try:
            # 执行被装饰的原函数
            result = func(*args, **kwargs)
        finally:
            # 无论函数执行成功/失败,都恢复原始get方法
            requests.get = original_get
        return result
    return wrapper

使用示例

@my_custom_decorator
def hello():
    # 这里的requests.get会自动带上我们定义的通用参数
    resp = requests.get("https://example.com")
    print(f"状态码: {resp.status_code}")

hello()

进阶优化:用上下文管理器分离逻辑

如果需要在多个地方复用替换逻辑,可以把替换/恢复的代码封装成上下文管理器,让装饰器代码更简洁:

import requests
from functools import wraps
from contextlib import contextmanager

@contextmanager
def override_requests_get():
    original_get = requests.get
    def wrapped_get(url, **get_kwargs):
        default_params = {
            "timeout": 15,
            "headers": {"User-Agent": "CustomBot/1.0"}
        }
        merged_kwargs = {**default_params, **get_kwargs}
        return original_get(url, **merged_kwargs)
    
    requests.get = wrapped_get
    try:
        yield
    finally:
        requests.get = original_get

# 装饰器复用上下文管理器
def my_custom_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        with override_requests_get():
            return func(*args, **kwargs)
    return wrapper

为什么比检查函数内容更优

你之前考虑的检查函数是否包含requests.get的方法存在明显缺陷:

  • 静态扫描代码字符串无法覆盖所有情况:比如函数内用了from requests import get、间接调用(比如通过其他函数封装的get),都会漏判。
  • 容易出现误判:比如函数里只是字符串提到了requests.get,并非实际调用。

而临时替换的方法是运行时动态拦截,只要函数在执行期间调用了requests.get,就会被我们的包装方法接管,完全覆盖所有调用场景,且对原代码零侵入。

内容的提问来源于stack exchange,提问作者xan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:24:58