python笔记36-装饰器之wraps

前言

前面一篇对python装饰器有了初步的了解了,但是还不够完美,领导看了后又提出了新的需求,希望运行的日志能显示出具体运行的哪个函数。

namedoc

__name__用于获取函数的名称,__doc__用于获取函数的docstring内容(函数的注释)

import time def func_a(a): '''func_a --> hello''' print("hello"+a) time.sleep(0.5) return True def func_b(b, c="xx"): '''func_b --> world''' print("world"+b+c) time.sleep(0.8) return True if __name__ == '__main__': print(func_a.__name__) # 结果 func_a print(func_a.__doc__) # func_a --> hello print(func_b.__name__) # func_b print(func_b.__doc__) # func_b --> world

装饰器加函数名称日志

在装饰器里面添加2行代码,打印正在运行函数的名称和docstring内容

import time def runtime(func): '''runtime decorators''' def wrapper(*args, **kwargs): '''wrapper inner fuction''' print("running function : %s" % func.__name__) print("docstring: %s" % func.__doc__) start = time.time() f = func(*args, **kwargs) # 原函数 end = time.time() print("运行时长:%.4f 秒" % (end-start)) return f return wrapper @runtime def func_a(a): '''func_a --> hello''' print("hello"+a) time.sleep(0.5) return True @runtime def func_b(b, c="xx"): '''func_b --> world''' print("world"+b+c) time.sleep(0.8) return True if __name__ == '__main__': func_a("a") print(func_a.__name__) print(func_a.__doc__)

运行结果

running function : func_a docstring: func_a --> hello helloa 运行时长:0.5008 秒 wrapper wrapper inner fuction

从运行的结果可以看出,func_a.__name__运行的结果是wrapper,func_a.__doc__运行的结果是wrapper inner fuction。
也就是说被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),那这个问题如何解决呢?
这就需要用到functools里面的一个wraps函数了

functools

当func_a函数被装饰后,导致了一个副作用:自身的函数属性和docstring内容变成了wrapper函数的属性了。
这里需用到functools里面的一个wraps的装饰器来消除这样的副作用。

import time from functools import wraps def runtime(func): '''runtime decorators''' @wraps(func) def wrapper(*args, **kwargs): '''wrapper inner fuction''' print("running function : %s" % func.__name__) print("docstring: %s" % func.__doc__) start = time.time() f = func(*args, **kwargs) # 原函数 end = time.time() print("运行时长:%.4f 秒" % (end-start)) return f return wrapper

只需在wrapper函数上加上@wraps(func)即可解决

运行结果

running function : func_a docstring: func_a --> hello helloa 运行时长:0.5004 秒 func_a func_a --> hello

类装饰器

带参数的装饰器,可以写成类装饰器

import time from functools import wraps class runtime(object): '''runtime class decorators''' def __init__(self, slowly=1): self.slowly = slowly def __call__(self, func): @wraps(func) def wrapper(*args, **kwargs): '''wrapper inner fuction''' print("running function : %s" % func.__name__) print("docstring: %s" % func.__doc__) start = time.time() f = func(*args, **kwargs) # 原函数 end = time.time() t = end-start time.sleep((self.slowly-1)*t) # 延迟效果 new_end = time.time() print("运行时长:%.4f 秒" % (new_end-start)) return f return wrapper @runtime(1.5) def func_a(a): '''func_a --> hello''' print("hello"+a) time.sleep(0.5) return True @runtime() def func_b(b, c="xx"): '''func_b --> world''' print("world"+b+c) time.sleep(0.8) return True if __name__ == '__main__': func_a("a") print(func_a.__name__) print(func_a.__doc__)

运行结果

running function : func_a docstring: func_a --> hello helloa 运行时长:0.7522 秒 func_a func_a --> hello

2019年《python3自动化UI+接口》课程5月25-7月27开课主讲老师:上海-悠悠上课方式:QQ群视频在线教学上课时间:每周六、周日晚上20:30-22:30报名费:2000

(0)

相关推荐

  • 一文看懂Python系列之装饰器(decorator)(工作面试必读)

    Python的装饰器(decorator)可以说是Python的一个神器,它可以在不改变一个函数代码和调用方式的情况下给函数添加新的功能.Python的装饰器同时也是Python学习从入门到精通过程中 ...

  • Python学习—装饰器

    学习Python已经有一段时间了,陆续学了一些基础部分,但是理解的不是很深刻,每过一段时间就会忘记,所以不得不写一些博客进行记录,加深自己的理解.这两个星期一直在研究装饰器,开始觉得很简单,但是只知其 ...

  • 完整版Python笔记|超级有用

    完整版Python笔记|超级有用

  • 胡希恕伤寒论学习笔记——36

    36.太阳与阳明合病,喘而胸满者,不可下,宜麻黄汤. 这一条说有阳明病,是因为有"满"的病症,也就是病家有胀满的情况.阳明病最常见的情况分成两类:一类是发热.汗出.不恶寒.反恶热, ...

  • 【python笔记】python java 语法,对比学习

    【python笔记】python java 语法,对比学习

  • python笔记2-冒泡排序

    前言 面试的时候经常有面试官喜欢问如何进行冒泡排序?这个问题相信能难倒一批英雄好汉,本篇就详细讲解如何用python进行冒泡排序. 一.基本原理 1.概念: 冒泡排序(Bubble Sort),是一种 ...

  • Selenium2+python自动化66-装饰器之运行失败截图

    前言 对于用例失败截图,很多小伙伴都希望在用例执行失败的时候能自动截图,想法是很好的,实现起来并不是那么容易. 这里分享下我的一些思路,当然目前还没找到完美的解决方案,我的思路是用装饰器去解决,希望有 ...

  • python笔记3-发送邮件(smtplib)

    前言 本篇总结了QQ邮箱和163邮箱发送邮件,邮件包含html中文和附件,可以发给多个收件人,专治各种不行,总之看完这篇麻麻再也不用担心我的邮件收不到了. 以下代码兼容python2和python3, ...

  • python笔记4-遍历文件夹目录os.walk()

    前言 如何遍历查找出某个文件夹内所有的子文件呢?并且找出某个后缀的所有文件 一.walk功能简介 1.os.walk() 方法用于通过在目录树种游走输出在目录中的文件名,向上或者向下. 2.walk( ...

  • python笔记5-python2写csv文件中文乱码问题

    前言 python2最大的坑在于中文编码问题,遇到中文报错首先加u,再各种encode.decode. 当list.tuple.dict里面有中文时,打印出来的是Unicode编码,这个是无解的. 对 ...

  • python笔记6-%u60A0和\u60a0类似unicode解码

    前言 有时候从接口的返回值里面获取到的是类似"%u4E0A%u6D77%u60A0%u60A0"这种格式的编码,不是python里面的unicode编码. python里面的uni ...