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

requests.Session子类新增参数时如何配置类型提示解决mypy报错

问题场景

以下代码运行时逻辑完全正常,但使用mypy执行静态类型检查时会抛出类型错误:

class NamePrintingSession(requests.Session):
    def request(self, method, url, name=None, **kwargs):
        print(name)
        return super().request(method, url, **kwargs)


nps = NamePrintingSession()
nps.get("http://www.google.com", name="wooo") # error: Unexpected keyword argument "name" for "get" of "Session"

报错原因明确:requests库的get()、post()等快捷方法原生实现虽然接收**kwargs做参数透传,但库自带的类型存根(stubs)固定了这些方法的参数约束,子类重写request()方法新增的参数,不会自动同步到从父类继承的其他快捷方法的类型定义中。

核心诉求:找到可行的类型配置方案,让子类继承来的get、post、delete等方法,在完整保留父类所有原有参数提示、文档关联的基础上,新增对name参数的类型支持;优先选择不需要手动重复声明每个方法全量参数的实现。


推荐实现方案

方案1:ParamSpec类型包装(最优,无冗余代码)

这个方案仅在类型检查层面对继承来的方法做参数扩展,运行时完全复用父类原生逻辑,不需要重写任何快捷方法,也能完整保留原有方法的参数提示、文档跳转能力。

依赖说明

  • Python 3.10及以上版本:直接使用标准库typing模块提供的ParamSpec、Concatenate、TypeVar即可
  • Python 3.10以下版本:安装typing_extensions依赖包,从该包导入上述类型对象即可

实现代码

from typing import Callable, Concatenate, ParamSpec, TypeVar
import requests

P = ParamSpec("P")
R = TypeVar("R")

def _append_name_arg(func: Callable[P, R]) -> Callable[Concatenate[str | None, P], R]:
    """仅用于类型标注的辅助函数,运行时直接返回原方法无额外逻辑"""
    return func

class NamePrintingSession(requests.Session):
    # 给需要支持name参数的快捷方法绑定扩展后的类型
    get = _append_name_arg(requests.Session.get)
    post = _append_name_arg(requests.Session.post)
    delete = _append_name_arg(requests.Session.delete)
    put = _append_name_arg(requests.Session.put)
    patch = _append_name_arg(requests.Session.patch)
    head = _append_name_arg(requests.Session.head)
    options = _append_name_arg(requests.Session.options)

    def request(self, method, url, name: str | None = None, **kwargs):
        print(name)
        return super().request(method, url, **kwargs)

方案优势

  • 代码冗余度极低:每个快捷方法只需要一行类型绑定代码,不需要复制父类方法的几十个参数定义
  • 无运行时损耗:辅助函数直接返回原方法对象,完全复用requests原生实现,不会引入额外逻辑
  • 类型提示完整:原有方法的所有参数提示、参数类型校验、文档跳转链接完全保留,仅额外新增了可选的name关键字参数支持
  • 兼容性好:mypy、pyright等主流静态类型检查工具都能正确识别扩展后的方法签名

注意事项

调用时name参数必须以关键字形式传入,这也符合这类HTTP请求方法的传参习惯,不会出现参数位置错位的问题。

方案2:本地类型存根覆盖(适合无代码侵入场景)

如果不想在业务代码中加入类型相关的辅助逻辑,可以在项目配置的类型存根目录下,为NamePrintingSession编写单独的.pyi类型存根文件,声明对应快捷方法追加name参数即可。
这种方案业务代码完全无侵入,但需要单独维护存根文件,后续如果需要扩展其他参数需要同步修改存根,维护成本略高于方案1。


不推荐方案

不建议手动重写每个get/post等快捷方法、在方法内部调用父类实现的写法:这种方式需要手动复制每个方法的全量参数签名,代码冗余度极高,后续requests版本更新调整方法参数时,还需要手动同步修改所有重写的方法,维护成本很高。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 09:06:52