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

使用Python装饰器时如何强制使用关键字参数?

问题:带参数验证的装饰器破坏强制关键字参数约束

我需要给SDK中的多个Python函数实现通用参数验证装饰器,这些函数参数类似但顺序未必一致,且必须保持参数可读性(不能仅依赖*args和**kwargs)。

现有一个用于验证a > b的装饰器:

from functools import wraps

def check_args(f):
    @wraps(f)
    def decorated_function(self, *args, **kwargs):
        a = kwargs["a"]
        b = kwargs["b"]
        
        if a < b:
            raise ValueError("a must be strictly greater than b")

        return f(self, *args, **kwargs)

    return decorated_function

将其应用在带强制关键字参数的方法上:

class MyClass(object):
    
    @check_args
    def f(self, *, a, b):
        return a + b
  • 用关键字参数调用MyClass().f(a=2, b=1)时,符合预期无错误;
  • 用位置参数调用MyClass().f(1, 2)时,装饰器抛出KeyError,但移除装饰器后,Python会抛出正确的TypeError(提示必须使用关键字参数)。

需要解决:如何让装饰器不破坏原函数的强制关键字参数约束,同时实现通用的参数验证?


正规解决方案:利用inspect模块解析函数签名

Python官方的inspect模块可以解析函数的参数签名,将传入的args和kwargs统一绑定到签名上,既保留原函数的参数校验逻辑,又能让装饰器通用地获取参数值。

修改后的装饰器代码

from functools import wraps
import inspect

def check_args(f):
    @wraps(f)
    def decorated_function(self, *args, **kwargs):
        # 获取原函数的参数签名
        sig = inspect.signature(f)
        try:
            # 绑定传入参数,触发原函数的参数校验(包括强制关键字参数检查)
            bound_args = sig.bind(self, *args, **kwargs)
            # 填充参数默认值
            bound_args.apply_defaults()
        except TypeError as e:
            # 直接抛出原函数会产生的错误,保持原生错误提示
            raise e
        
        # 从绑定结果中提取需要验证的参数
        a = bound_args.arguments['a']
        b = bound_args.arguments['b']
        
        if a < b:
            raise ValueError("a must be strictly greater than b")

        return f(self, *args, **kwargs)

    return decorated_function

效果验证

  1. 位置参数调用:MyClass().f(1, 2)会抛出和原函数一致的TypeError: f() takes 1 positional argument but 3 were given,强制用户使用关键字参数;
  2. 非法关键字参数:MyClass().f(a=1, b=2)会抛出装饰器定义的ValueError: a must be strictly greater than b;
  3. 合法调用:MyClass().f(a=2, b=1)正常返回结果3。

方案优势

  • 完全遵循Python原生参数校验逻辑,错误提示和原生行为一致;
  • 基于官方inspect模块实现,通用性强,适配不同参数顺序的函数;
  • 保留原函数的参数可读性,无需修改函数定义为*args/**kwargs。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:30:59