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

Python装饰器如何传入**kwargs作为参数及相关报错解决

错误原因分析
  • 核心问题是变量作用域混淆:你调用@deco(3,4,like="andrew")时传入的like参数,是被外层deco函数的**kwargs接收的,属于deco的作用域变量。而你内层longer函数定义里的**kwargs,是用来接收被装饰函数greet调用时传入的参数,两个kwargs完全是不同作用域下的独立变量,你在longer里取当前调用参数的kwargs['like'],但你调用greet('r')时没有传like参数,自然抛出KeyError。
  • 你尝试的第二种写法def deco(x,y,'like'):本身存在语法错误,Python函数的形参不能是字符串字面量。
  • 你尝试的第一种写法def deco(x,y,like):语法本身是合法的,报错原因还是和最开始的问题一样,没有正确取用deco层拿到的like参数。
修复方案

只需要把deco层拿到的like参数直接在longer里引用即可,不需要从longer的调用参数里取,修改后的代码如下:

import time
import math

def deco(x,y,*args,**kwargs): 
    # 先把deco层拿到的like参数存下来,避免和内层变量命名冲突
    deco_like = kwargs.get('like')
    def short(func):
        # 内层的参数换个命名更不容易混淆
        def longer(r,*args,**call_kwargs):
            print("before func exe")
            begin = time.time()
            func(r)
            end = time.time()
            print("after func exe")
            # 直接引用deco层拿到的参数
            print("I am ", deco_like)
            print("Total time taken in : ", func.__name__, end - begin)
        return longer
    return short

@deco(3,4,like="andrew")   
def greet(r):
    r = "I will be selelcted"
    print(r)
    
print(greet('r'))

如果你希望like是deco的必填关键字参数,也可以直接把deco的参数定义改成def deco(x,y,*, like):,星号表示后面的参数必须用关键字传参,调用方式还是和之前一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 20:15:03