当前位置: 首页 > 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.gsyq.cn/news/21680.html

相关文章:

  • 大素材毕业设计选题推荐-基于大数据的全球经济指标数据分析与可视化环境-Hadoop-Spark-数据可视化-BigData
  • 在 gitea 服务器端查询 lfs 文件占用情况
  • HDR图像生成算法详解
  • 基于MATLAB的二自由度机械臂PID控制仿真
  • Ventoy引导Kali live USB持久化
  • 【面试题】人工智能工程师高频面试题汇总:循环神经网络篇(题目+答案)
  • 做了个手机上的“视频播放器”,获益匪浅
  • CEF关闭流程
  • AI一周资讯 251005-251015
  • 075_尚硅谷_位运算深度讲解
  • iOS框架内存中占用很高的ttc文件是否正常
  • MPC模型预测控制:原理、设计与MATLAB实现
  • 美股 SaaS 巨头如何用 Karpenter 节省 1/4 的 EC2 成本
  • 题解:qoj7303 City United
  • 基于模糊深度信念网络(FDBN)的情感分析实现与优化
  • Python 实现 Ping 功能
  • 2025年焊接机器人厂家最新权威推荐榜:激光/自动/智能/工业/国产焊接机器人系统、机器人焊接设备、汽车/钢结构/氩弧焊焊接机器人公司精选
  • 2025年保洁公司最新权威推荐榜单:专业家政服务与深度清洁口碑优选,家庭保洁、企业保洁、开荒保洁全方位解析
  • 多物理域协同 + 三维 CAD 联动!ADS 2025 解锁射频前端、天线设计新体验
  • MySQL—— 备份与恢复
  • 读书笔记:时间间隔类型:轻松管理时长与时间点
  • 2025 年最新推荐!除尘器厂家权威排行榜发布,深度解析各品牌技术实力与市场口碑
  • 实用指南:【Git】项目管理全解
  • 在浏览器播放多个视频 opencv+Nicegui
  • 达梦定时任务更新阻塞信息到表
  • 2025年千斤顶厂家最新权威推荐排行榜:液压千斤顶、机械千斤顶、电动千斤顶源头厂家综合实力深度解析
  • VKD104CR是永嘉微VINKA推出低功耗2路触摸芯片该芯片具有较高的集成度
  • STM32学习路线!600+讲课程!软硬件兼修:裸机+RTOS+LVGL+硬件设计+项目实战 (STM32多核心开发板)
  • 【2025-10-11】适应变化
  • C语言的学习——常量