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

如何修改Python装饰器实现多层装饰后保留原函数名输出?

问题分析与解决方案

你的问题核心在于装饰器没有保留原函数的元数据——每次装饰后,被包装函数的__name__属性会被替换成包装函数的名字wrapper。多层装饰时,前两次装饰的对象其实是上一层的wrapper,所以打印的是wrapper,只有最后一次才会触达原hello函数的名字。

要让多层装饰器都能正确识别原函数名,我们可以借助Python标准库functools中的wraps工具,它能帮我们把原函数的关键元数据(比如__name__、__doc__)复制到包装函数上。

修改后的完整代码

import functools

def wrap(function):
    @functools.wraps(function)  # 关键:保留原函数的元数据
    def wrapper(*args, **kwargs):
        print(function.__name__)
        return function(*args, **kwargs)
    return wrapper

# 三层装饰hello函数
@wrap
@wrap
@wrap
def hello():
    print("Hello, world!")

hello()

运行结果

hello
hello
hello
Hello, world!

原理说明

  • functools.wraps本质是一个装饰器,它会自动将被装饰函数(这里的function)的__name__、__module__、__doc__等属性复制到包装函数wrapper上。
  • 这样每次装饰时,wrapper都会继承当前被装饰对象的原函数名——哪怕是上一层的wrapper,也因为被wraps处理过,保留了最初hello的名字,所以三次打印都会输出hello。

如果不想依赖标准库,也可以手动复制元数据,比如在wrapper函数后添加:

wrapper.__name__ = function.__name__
wrapper.__doc__ = function.__doc__

但functools.wraps是官方推荐的更简洁、全面的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:18:04