标准库 functools 中的 wrap 函数用于包装函数, 不改变原有函数的功能, 仅改变原有函数的一些属性, 例如 __name__, __doc__, __annotations__ 等属性

先看一个简单的示例

import functoolsdef func_1(x: str) -> None:"""function:return: None"""print("func_1", x)@functools.wraps(func_1)
def demo():"""demo:return: None"""print("demo")print("demo name:", demo.__name__)
print("demo doc:", demo.__doc__)
print("demo annotations:", demo.__annotations__)
demo()
print("func_1 is demo's wrap:", func_1 is demo.__wrapped__)

输出

demo name: func_1
demo doc: function:return: Nonedemo annotations: {'x': <class 'str'>, 'return': None}
demo
func_1 is demo's wrap: True

使用 func_1 去包装 demo 函数, demo 函数本身的功能没变(仍打印 “demo”), 但是 __name__(函数名称), __doc__(函数文档), __annotations__(函数注释) 等属性变了, 而且 __wrapped__ 属性指向包装函数

functools.wrap 可用于装饰器的内层函数, 抵消装饰器的副作用, 因为使用装饰器后, 原函数被内层函数赋值覆盖, 函数名称等信息丢失了(装饰器仅仅是不改变函数原有功能)

def info(func):def wrap(a, b):return func(a, b)return wrap@info
def multiply(x, y):return x * yprint("multiply name:", multiply.__name__)

打印

multiply name: wrap

使用装饰器后, multiply 指向内层函数 wrap, 所以名称变为 wrap

可以对内层函数进行包装

def info(func):@functools.wraps(func)def wrap(a, b):return func(a, b)return wrap@info
def multiply(x, y):return x * yprint("multiply name:", multiply.__name__)

输出

multiply name: multiply

@info 装饰器等价于 multiply = info(multiply), 所以 func 指向原始 multiply 函数, @functools.wraps(func) 使用原始 multiply 函数包装 wrap 函数, 随后 wrap 函数覆盖原始 multiply 函数

注意 wrap 函数与原始 multiply 函数形参必须兼容

Python functools.wraps 详解相关推荐

  1. python functools 使用详解

    文章目录 1.functools.cmp_to_key(func) 2.@functools.lru_cache(maxsize=128, typed=False) 3.functools.parti ...

  2. python协程详解

    目录 python协程详解 一.什么是协程 二.了解协程的过程 1.yield工作原理 2.预激协程的装饰器 3.终止协程和异常处理 4.让协程返回值 5.yield from的使用 6.yield ...

  3. Python中lambda详解(包括内置函数map、reduce、filter、sorted、max)

    文章目录 一.lambda是什么? 1.lambda语法 2.语法详解 二.lambda的使用 1.定义 2.调用 3.替换 4.作返回值 三.lambda作参数 1.map函数 2.reduce函数 ...

  4. python20191031_20191031:Python取反运算详解

    20191031:Python取反运算详解 取反运算:~3 == 4 1.对于数字 3 =======>转换为二进制表示为011 2.对011取反为100 3.为什么表示-4 a.计算机用补码表 ...

  5. Python字符编码详解

    Python字符编码详解 转自http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html Python字符编码详解 本文简单介绍了各种常用的 ...

  6. python的执行过程_在交互式环境中执行Python程序过程详解

    前言 相信接触过Python的伙伴们都知道运行Python脚本程序的方式有多种,目前主要的方式有:交互式环境运行.命令行窗口运行.开发工具上运行等,其中在不同的操作平台上还互不相同.今天,小编讲些Py ...

  7. python functools.wraps functools.partial实例解析

    一:python functools.wraps 实例 1. 未使用wraps的实例 #!/usr/bin/env python # coding:utf-8def logged(func):def ...

  8. windows上安装Anaconda和python的教程详解

    一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...

  9. python变量类型-Python 变量类型详解

    变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据类型,这些变量可以存储整 ...

最新文章

  1. PNAS:水稻微生物组
  2. [转]建一个XMLHttpRequest对象池
  3. 后台产品经理跳坑“指南”
  4. STM32开发 -- 蓝牙开发详解(1)
  5. BZOJ2059: [Usaco2010 Nov]Buying Feed 购买饲料
  6. Silverlight:Dependency Property(依赖属性)学习笔记
  7. 数据结构精品电子书分享之《数据结构题集(C语言版)》
  8. excel工作簿合并怎么处理?
  9. TMS570-4-RTI_DWD看门狗
  10. 《游戏系统设计三》游戏服务器线上出bug,怎么办?急,在线等!热更新
  11. 什么是资本运营的核心?
  12. unity2D动画-角色切片与2DAnimation插件做动画
  13. Linux发行版幽灵漏洞的backport
  14. sqlilabs Less-8 盲注浅学习
  15. linux查看dns命令
  16. ANSYS APDL经典界面如何导入多个材料模型
  17. Spring框架(Spring5新功能)
  18. python权限设置
  19. Epson me 打印机实现CorelDraw12中A4纸张无边距打印
  20. Windows脚本初探之Windows Script Host(WSH)

热门文章

  1. google 地图回中国了
  2. RGB 9, 73, 247 的 HVS 值是多少
  3. 红米note12turbo参数配置 Redminote12turbo值得买吗
  4. window bat脚本 扩充变量 %dp0
  5. 使用Modeler和WID协作实现简单的信用卡申请及进度查询的业务流程
  6. line.strip().split( )
  7. 民生---曝深圳西乡“麻布邨”篮球场被占为停车场乱象(有图有真相)
  8. 移动互联网测试岗——招聘现状
  9. 深入理解Java中的不可变对象
  10. 如何同时使用内网和外网