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

如何在装饰器工厂中使用@wraps装饰器?

如何在装饰器工厂中使用@wraps装饰器?

我明白你是在练手装饰器工厂,这个乘法的例子虽然没啥实际用处,但用来理解原理超合适~咱们直接说重点:@wraps 应该放在最内层的 wrapper 函数上面,作用是把被装饰函数的元数据(比如函数名、文档字符串这些)复制到 wrapper 函数上,避免原函数的“身份信息”丢失。

给你修改好的完整代码,一看就懂:

from functools import wraps

def multiply(numbers):
    def decorator(f):
        # 把@wraps(f)放在这里,专门装饰wrapper函数
        @wraps(f)
        def wrapper(*args, **kwargs):
            num1 = numbers[0]
            for num2 in numbers[1:]:
                num1 = num1 * num2
            print(num1)
            return f(*args, **kwargs)  # 这里建议把**kwargs也传进去,匹配原函数的参数定义
        return wrapper
    return decorator

@multiply(numbers=[1, 2, 3])
def input(**kwargs):
    print("That was the multiplied number.")

input()

为啥要放在这儿?简单说:装饰器最终是用 wrapper 函数替换了原来的 input 函数,如果不加 @wraps(f),你试试打印 input.__name__,会输出 'wrapper' 而不是 'input'——这会导致后续如果有依赖函数元数据的逻辑出问题。加了之后,wrapper 就会“继承”原函数 f 的所有元数据,看起来就像没被装饰过一样。

另外顺便提一句,你原代码里 wrapper 返回 f(*args),但原函数 input 定义是接受 **kwargs,最好改成 return f(*args, **kwargs),这样传关键字参数的时候也能正常工作哦~

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 08:34:32