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

保留functools.wraps时,如何为类实例方法装饰器添加正确类型注解?

问题:保留functools.wraps时解决Pyright参数报错

以下是示例代码:

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

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

def deco(func: Callable[Concatenate[R, int, int, P], None]):
    @functools.wraps(func)
    def wrapper(self, *args: P.args, **kwargs: P.kwargs):
        return func(self, 1, 2, *args, **kwargs)
    return wrapper


class A:
    @deco
    def main(self, a, b, c):
        pass


a = A()
a.main(3)

问题现象

最后一行代码a.main(3)中,Pyright给出报错信息:Argument missing for parameter "c"。移除@functools.wraps(func)后报错即可消失,但需在保留该装饰器的前提下解决问题,且代码结构不可更改。

解决方案

核心问题是装饰器的返回类型未明确标注,导致Pyright无法正确推断wrapper的参数签名。只需给deco函数添加返回类型注解-> Callable[P, None],明确告知类型检查器:装饰器返回的函数仅接受P所定义的参数,而非原函数的完整参数列表。

修改后的装饰器定义如下:

def deco(func: Callable[Concatenate[R, int, int, P], None]) -> Callable[P, None]:
    @functools.wraps(func)
    def wrapper(self, *args: P.args, **kwargs: P.kwargs):
        return func(self, 1, 2, *args, **kwargs)
    return wrapper

添加注解后,Pyright就能正确识别a.main(3)的参数合法性——装饰后的main函数仅需接收原函数中self、a、b之外的参数c(对应示例中的3)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 03:03:20