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

如何修改Python装饰器添加的函数签名,解决Pylint报错并让VSCode识别新增可选参数?

如何修改Python装饰器添加的函数签名,解决Pylint报错并让VSCode识别新增可选参数?

我最近写了个叫add_suffix的Python装饰器,作用是给目标函数加一个suffix关键字参数,运行起来没问题,但Pylint一直报E1123: Unexpected keyword argument 'suffix'的错,而且VSCode也识别不到这个新增的可选参数,这可太头疼了!先看看我的代码:

import functools


def add_suffix(func):
    @functools.wraps(func)
    def wrapper(*args, suffix: str = '!', **kwargs):
        return f'{func(*args, **kwargs)}{suffix}'

    return wrapper


@add_suffix
def my_function():
    return '1'

# E1123: Unexpected keyword argument 'suffix' in method call (unexpected-keyword-arg)
print(my_function(suffix='!!'))

别着急,我来给你两种解决方案,都能解决这个问题:

方案一:用现代类型注解(推荐,Python 3.10+)

我们可以用typing模块里的ParamSpec、TypeVar和Concatenate来给装饰器做精确的类型注解,让类型检查工具和编辑器清楚知道装饰器给函数新增了参数。

修改后的代码如下:

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

# 定义参数规格和返回值类型变量
P = ParamSpec('P')
R = TypeVar('R')

def add_suffix(func: Callable[P, R]) -> Callable[Concatenate[P.args, P.kwargs, {'suffix': str}], str]:
    @functools.wraps(func)
    def wrapper(*args: P.args, suffix: str = '!', **kwargs: P.kwargs) -> str:
        return f'{func(*args, **kwargs)}{suffix}'

    return wrapper

@add_suffix
def my_function():
    return '1'

# 现在Pylint不会报错,VSCode也能识别suffix参数了
print(my_function(suffix='!!'))

这里的ParamSpec用来捕获原函数的参数规格,Concatenate用来把原函数的参数和新增的suffix参数合并起来,这样类型检查工具就能准确识别到装饰后的函数支持suffix参数了。

方案二:修改函数注解(快速hack方法)

如果你不想用复杂的类型注解,也可以直接给装饰后的函数添加参数注解,让编辑器和Pylint识别到suffix参数:

import functools

def add_suffix(func):
    @functools.wraps(func)
    def wrapper(*args, suffix: str = '!', **kwargs):
        return f'{func(*args, **kwargs)}{suffix}'

    # 把suffix参数的注解添加到wrapper的注解里
    wrapper.__annotations__['suffix'] = str
    return wrapper

@add_suffix
def my_function():
    return '1'

print(my_function(suffix='!!'))

这种方法通过修改函数的__annotations__属性,手动添加suffix的类型注解,虽然简单,但不如方案一规范,适合快速解决问题的场景。

另外你提到之前看到ParamSpec的文档说“不能在*args和**kwargs之间放关键字-only参数”,其实我们这里的写法是符合规范的——suffix作为关键字-only参数放在*args之后、**kwargs之前,是Python允许的语法,而类型注解里用Concatenate也正确表达了参数的结构,所以不会有问题。

备注:内容来源于stack exchange,提问作者illusional

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 12:23:08