内容简介:Python装饰器举例分析
概述
装饰器本质上是一个 Python 函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
我们要需要一个能测试函数运行时间的decorator,可以定义如下:
def timer(func): def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print("Run time is: %s" % (end_time - start_time)) return res return wrapper
因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。 我们要借助Python的@语法 ,把decorator置于函数的定义处:
@timer def fun(): time.sleep(1) print("This is a test") return "OK"
运行结果就是:
This is a test Run time is: 1.0000572204589844 OK
把@timer放在fun ()处就相当于执行了语句:
fun = timer(fun)
如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,比如加上名字:
def timer(name): def decorator(func): def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print("Name is: %s ; Run time is: %s" % (name, (end_time - start_time))) return res return wrapper return decorator
调用及结果显示如下:
@timer("Lance#") def fun(): time.sleep(1) print("This is a test") return "OK"
This is a test Name is: Lance# ; Run time is: 1.0000572204589844 OK
和两层嵌套的decorator相比,三层嵌套的效果是这样的:
fun = timer("Lance#")(fun)
因为函数也是对象,它也有__name__等属性。
在未加装饰器之前的fun()函数,调用 fun的__name__属性结果是 'fun',但经过decorator装饰之后的函数,它们的__name__已经从原来的'fun'变成了'wrapper'
所以,需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。
Python内置的functools.wraps就可以完成这个任务,所以,一个完整的decorator的写法如下:
import functools def timer(func): @functools.wraps(func) def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print("Run time is: %s" % (end_time - start_time)) return res return wrapper
整体代码如下:
__Author__ = "Lance#" # -*- coding = utf-8 -*- import time import functools def timer(name): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print("Name is: %s ; Run time is: %s" % (name, (end_time - start_time))) return res return wrapper return decorator @timer("Lance#") def fun(): time.sleep(1) print("This is a test") return "OK" if __name__ == '__main__': print(fun())
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 设计模式应用举例
- Qt事件系统与应用举例
- 前端模板引擎Handlebars理解与举例
- 举例简介Lua中函数的基本用法
- 标注图+部分举例聊聊Vue生命周期
- Qt ModelView教程(二)——应用举例(一)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。