当前位置: 首页 > news >正文

@wraps(func)

@wraps(func) 是 Python 标准库 functools 模块提供的一个装饰器,主要用于保留被装饰函数的元信息(metadata)。当我们使用自定义装饰器包装函数时,被装饰后的函数会丢失原函数的名称、文档字符串等信息,而 @wraps(func) 可以解决这个问题。

为什么需要 @wraps(func)

先看一个不使用 @wraps 的例子,观察装饰器对函数元信息的影响:

def my_decorator(func):def wrapper(*args, **kwargs):"""这是 wrapper 函数的文档字符串"""return func(*args, **kwargs)return wrapper@my_decorator
def original_func():"""这是原函数的文档字符串"""print("原函数执行")# 查看被装饰后的函数信息
print("函数名:", original_func.__name__)  # 输出:wrapper(而非 original_func)
print("文档字符串:", original_func.__doc__)  # 输出:这是 wrapper 函数的文档字符串(而非原函数的)

可以看到,被装饰后的 original_func 实际上变成了 wrapper 函数,因此它的元信息(__name____doc__ 等)也被替换成了 wrapper 的信息。这会导致:

  • 调试时难以识别函数身份;
  • 生成文档时无法正确提取原函数的说明;
  • 依赖函数元信息的代码(如反射)出现异常。

@wraps(func) 的作用

@wraps(func) 的本质是将原函数 func 的元信息“复制”到装饰器内部的 wrapper 函数上,让 wrapper 函数看起来更像原函数。

修改上面的例子,添加 @wraps(func)

from functools import wrapsdef my_decorator(func):@wraps(func)  # 保留原函数元信息def wrapper(*args, **kwargs):"""这是 wrapper 函数的文档字符串"""return func(*args, **kwargs)return wrapper@my_decorator
def original_func():"""这是原函数的文档字符串"""print("原函数执行")# 再次查看被装饰后的函数信息
print("函数名:", original_func.__name__)  # 输出:original_func(正确保留)
print("文档字符串:", original_func.__doc__)  # 输出:这是原函数的文档字符串(正确保留)

此时,original_func 的元信息被正确保留,解决了装饰器导致的元信息丢失问题。

@wraps 复制的元信息包括:

@wraps 会将原函数的以下核心元信息复制到 wrapper 函数:

  • __name__:函数名称;
  • __doc__:文档字符串(docstring);
  • __module__:函数所在的模块;
  • __annotations__:函数的参数和返回值注解;
  • __defaults__:函数的参数默认值;
  • 其他与函数身份相关的属性。

实际应用场景

@wraps 在以下场景中尤为重要:
1.** 调试 :确保调试工具(如 pdb)显示的是原函数名,而非 wrapper
2.
文档生成 :自动文档工具(如 Sphinx)能正确提取原函数的文档字符串;
3.
装饰器嵌套 :多层装饰器时,保留元信息可避免身份混淆;
4.
依赖元信息的框架 **:某些框架(如 Flask、Django)会通过函数名或文档字符串实现特定功能,需确保元信息正确。

总结

@wraps(func) 是装饰器开发中的“最佳实践”,它的作用是保留被装饰函数的元信息,避免因装饰器包装导致函数身份、文档等信息丢失。使用时只需将其放在装饰器内部的 wrapper 函数上方,并传入原函数 func 作为参数即可。

在之前的“递归计时器装饰器”中,@wraps(func) 确保了被装饰的递归函数(如 factorialfibonacci)在调试或查看元信息时,仍能正确显示其原始名称和文档,而不是内部的 wrapper 函数信息。

http://www.jsqmd.com/news/14203/

相关文章:

  • antdx 如何接入dify
  • 大素材毕业设计选题推荐-基于大数据的全球经济指标数据分析与可视化环境-Hadoop-Spark-数据可视化-BigData
  • D. MAD Interactive Problem
  • 在 gitea 服务器端查询 lfs 文件占用情况
  • HDR图像生成算法详解
  • Introduction: Why Optimization?
  • 基于MATLAB的二自由度机械臂PID控制仿真
  • Spring AOP原理
  • Azure VM (46) 分布式tcping监控
  • Ventoy引导Kali live USB持久化
  • 知识库管理工具深度测评:ONES、Confluence 等10款工具全面对比
  • 从SGD到AdamW:深度学习优化器演进全解析与实践指南
  • 【面试题】人工智能工程师高频面试题汇总:循环神经网络篇(题目+答案)
  • 做了个手机上的“视频播放器”,获益匪浅
  • CEF关闭流程
  • AI一周资讯 251005-251015
  • 2025 年中空百叶源头厂家最新推荐排行榜:聚焦国内优质供货商,助力客户精准选购可靠产品光能/光伏/电动/光动中空百叶厂家推荐
  • 2025年学校家具定制厂家最新权威推荐榜:全屋定制/衣柜/厨柜/酒柜/鞋柜/猫柜/酒店办公家具/电视柜/书包柜/图书架/宿舍上下床
  • 075_尚硅谷_位运算深度讲解
  • iOS框架内存中占用很高的ttc文件是否正常
  • Linux配置SSH名称通信
  • cors跨域疑问解决
  • D. Not Alone
  • MPC模型预测控制:原理、设计与MATLAB实现
  • 2025年焊接变位机厂家最新权威推荐榜:双轴变位机专业制造商,高效稳定助力智能焊接升级
  • 体育视频分析中的计算机视觉技术创新
  • 美股 SaaS 巨头如何用 Karpenter 节省 1/4 的 EC2 成本
  • 2025年法兰罩厂家最新权威推荐榜:专业防护与精密制造,工业管道安全守护者优选品牌
  • 2025 年膜结构厂家最新推荐排行榜:含车棚 / 看台 / 景观等产品实力企业盘点与选择指南
  • 题解:qoj7303 City United