Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变)。

这样变化后对程序会造成一定的影响,如在flask框架中的一些函数添加自定义的decorator,添加后由于函数名和函数的doc发生了改变,这会对测试造成一定的影响。这是会可以使用functools包提供的wraps方法的decorator来消除这种副作用。写一个decorator的时候,在实现之前加上functools的wrap,它能保留原有函数的名称和docstring。

wraps是在装饰器中使用,保留原来函数的属性

functools.wraps

使用装饰器可以极大的复用了代码,但它也有一个缺点就是原函数的元信息不见了,比如函数的docstring、__name__、参数列表等。

示例代码1:

def logged(func):def with_logging(*args, **kwargs):print(func.__name__ + 'was called')return func(*args, **kwargs)return with_logging@logged
def test():"""does some math:param x::return:"""x = 6return x ** 2#  上述函数等价于
def test2():"""does some math:param x::return:"""x = 5return x ** 2a = test()
print(a)
b = logged(test2)
print(b())print("*" * 100)print(test.__name__)
print(test.__doc__)print("*" * 100)print(test2.__name__)
print(test2.__doc__)

运行结果:

上述代码执行结果中不难看出,函数test被with_logging取代了,当然它的docstring,__name__等信息就变成了with_logging函数的信息了。

出现上述问题有时候是问题是挺严重的,这时候我们可以使用functools.wraps库,wraps本身也是一个装饰器,它能够把原函数的元信息拷贝到装饰器函数中,这使用装饰器函数也有原函数一样的元信息了。

示例代码2:

from functools import wrapsdef logged(func):@wraps(func)def with_logging(*args, **kwargs):print(func.__name__ + 'was called')return func(*args, **kwargs)return with_logging@logged
def test():"""does some math:param x::return:"""x = 6return x ** 2#  上述函数等价于
def test2():"""does some math:param x::return:"""x = 5return x ** 2a = test()
print(a)
b = logged(test2)
print(b())print("*" * 100)print(test.__name__)
print(test.__doc__)print("*" * 100)print(test2.__name__)
print(test2.__doc__)

运行结果:

示例代码3:

from functools import wrapsdef wrapper(func):@wraps(func)def inner(*args, **kwargs):res = func(*args, **kwargs)print("func.__name__:", func.__name__)print("func.__doc__:", func.__doc__)return resreturn inner@wrapper
def funcs():"""funcs functions"""passfuncs()
print(funcs)  # <function funcs at 0x0000026852CB4438>

运行结果:

示例代码4:

def wrapper(func):def inner(*args, **kwargs):res = func(*args, **kwargs)print("func.__name__:", func.__name__)print("func.__doc__:", func.__doc__)return resreturn inner@wrapper
def funcs():"""funcs functions"""passfuncs()
print(funcs)  # <function wrapper.<locals>.inner at 0x0000021E46384438>

运行结果:

python中wraps函数用法详情相关推荐

  1. format函数python的顺序_[转载] Python中format函数用法

    Python中format函数用法 format优点 format是python2.6新增的格式化字符串的方法,相对于老版的%格式方法,它有很多优点. 1.不需要理会数据类型的问题,在%方法中%s只能 ...

  2. python中max函数用法_Python中max函数用法实例分析

    Python中max函数用法实例分析 更新时间:2015年07月17日 15:45:09 作者:优雅先生 这篇文章主要介绍了Python中max函数用法,实例分析了Python中max函数的功能与使用 ...

  3. python中property函数_python 邮件表格Python中property函数用法实例分析

    本文实例讲述了Python中property函数用法.分享给大家供大家参考,具体如下: 通常我们在访问和赋值属性的时候,都是在直接和类(实例的)的__dict__打交道,或者跟数据描述符等在打交道.但 ...

  4. python中sleep函数用法_sleep函数函数介绍与使用方法详解

    在一些竞猜的网站中,如果我们需要做一个定时执行的功能,比如有一道题,在十秒之内要完成,否则显示"您已超时",如果完成,则跳转到下一道题上面,而这中间有一个十秒的停顿,这样的功能是怎 ...

  5. python中sleep函数用法_python中sleep函数用法实例分析

    本文实例讲述了python中sleep函数用法.分享给大家供大家参考.具体如下: Python中的sleep用来暂停线程执行,单位为秒 #------------------------------- ...

  6. Python中format函数用法

    Python中format函数用法 format优点 format是python2.6新增的格式化字符串的方法,相对于老版的%格式方法,它有很多优点. 1.不需要理会数据类型的问题,在%方法中%s只能 ...

  7. python range函数返回的是什么,python中range函数用法是什么

    python中range函数用法:[range()]函数可创建一个整数列表,一般用在for循环中,函数语法为[range(start, stop[, step])],其中start是开始计数,stop ...

  8. python中readlines函数用法,python中read() readline()以及readlines()用法

    我们谈到"文本处理"时,我们通常是指处理的内容.Python 将文本文件的内容读入可以操作的字符串变量非常容易.文件对象提供了三个"读"方法: .read(). ...

  9. python中setattr()函数用法详解

    setattr() 函数对应函数 getattr(),用于设置属性值,该属性不一定是存在的. getattr()用法详见博文:python中getattr()函数用法详解_IT之一小佬的博客-CSDN ...

最新文章

  1. linux中实现pxe的自动安装
  2. 对DBF的操作建议用微软的驱动和新的链接字符串。
  3. css优先级和权重问题
  4. 中等职计算机应用基础,中等职业计算机应用基础答案
  5. Pygal简介、画廊--各种图形绘图代码
  6. gdiplus判断一个点是否在圆弧线上_面试前必读!!!原生JS补给(上)
  7. fvdm 跟驰模型 matlab仿真_MATLAB数值计算在光学仿真和教学中的应用
  8. 世界笔记本巨头厂商 Compal 被勒索1700万美元
  9. 同时删除多个 Txt 文本文档空白行
  10. linux SysV IPC实现
  11. 一位美国教授给研究生的怎样记读书笔记的建议(中文总结)
  12. SSM思想—阶段性总结
  13. matlab多重积分如何使用方法,MATLAB在《高等数学》中的应用_多重积分
  14. 漫画|电话会议炸出了同事里的隐形富豪
  15. Retrofit自定义GsonConverter处理请求错误异常处理
  16. SaaS、PaaS、DaaS、IaaS四种云系统说明
  17. 2020-12-27 python安装包相关命令
  18. Rocket的启动流程
  19. 用Kettle的一套流程完成对整个数据库迁移
  20. shell十三问--shell教程

热门文章

  1. 【Python】-实战项目
  2. MATLAB-- mean()的使用
  3. Activiti配置
  4. 星邦智能冲刺上交所:年营收18.8亿 拟募资14亿
  5. 角色转换之间—我的2012年总结
  6. php curl 优化下载微信头像
  7. Cloneable接口
  8. 2016年31款轻量高效的开源 JavaScript 插件和库
  9. STM8L051F3_0b_开发环境搭建
  10. 我的第一款Html5小游戏《接水果》,防android平台一款应用