本文共 2750 字,大约阅读时间需要 9 分钟。
在阅读代码中,发现@***的什么的,原来这个就是大名鼎鼎的装饰器,然后就学习了下装饰器,记录下学习心得。
python装饰器就是用于拓展原来函数功能的一种特殊的函数,特殊之处在于它返回的是一个函数。
优点:不用更改原代码前提下可以新增函数的功能。
应用场景:插入日志,性能测试,事务处理,提取大量函数中与本身功能无关的类似代码,达到代码重复使用的目的。
用例子说明事物是最好懂的。
首先亮出原代码
import time def func(): print("hello") time.sleep(1) print("tian")
要求:记录函数的执行总时间
常规想法:更改原代码。
import timedef func(): startTime = time.time() print("hello") time.sleep(1) print("tian") endTime = time.time() msecs = (endTime - startTime)*1000 print("time is %d ms" %msecs)
思考:如果使用装饰器呢?琢磨下面的代码就很好理解了。
import timedef decorator(fun): def wrapper(): startTime = time.time() fun() endTime = time.time() msecs = (endTime - startTime)*1000 print("time is %d ms" %msecs) return wrapper@decoratordef fun(): print("hello") time.sleep(1) print("tian")if __name__=="__main__": f=fun f()
3.1 带参数的装饰器
import timedef decorator(fun): def wrapper(a,b): startTime=time.time() fun(a,b) endTime=time.time() msecs=(endTime - startTime)*1000 print("time is %d ms" %msecs) return wrapper@decoratordef fun(a,b): print("hello") time.sleep(1) print("result is %d" %(a+b))if __name__=="__main__": f=fun f(3,4)
3.2 带有不定参数的装饰器
以*开头,可以传多个参数,**是形参中按照关键字传值把多余的传值以字典的方式呈现。
*args:表示将实参中按照位置传值,多出来的值都给args,且以元祖的方式呈现。
**kwargs:表示形参中按照关键字传值把多余的传值以字典的形式呈现
import timedef decorator(fun): def wrapper(*args,**kwargs): startTime=time.time() fun(*args,**kwargs) endTime=time.time() msecs=(endTime - startTime)*1000 print("time is %d ms" %msecs) return wrapper@decoratordef fun1(a,b): print("hello") time.sleep(1) print("result is %d" %(a+b))@decoratordef fun2(a,b,c): print("hello") time.sleep(1) print("result is %d" %(a+b+c))if __name__=="__main__": fun1(3,4) fun2(3,4,5)
3.3 多个装饰器
#多个装饰器import timedef deco01(func): def wrapper(*args, **kwargs): print("this is deco01") startTime = time.time() func(*args, **kwargs) endTime = time.time() msecs = (endTime - startTime)*1000 print("time is %d ms" %msecs) print("deco01 end here") return wrapperdef deco02(func): def wrapper(*args, **kwargs): print("this is deco02") func(*args, **kwargs) print("deco02 end here") return wrapper@deco01@deco02def func(a,b): print("hello,here is a func for add :") time.sleep(1) print("result is %d" %(a+b))if __name__ == '__main__': f = func f(3,4)
输出结果:
this is deco01this is deco02hello,here is a func for add :result is 7deco02 end heretime is 1000 msdeco01 end hereProcess finished with exit code 0
观察输出顺序可以大概推断执行的顺序。多个装饰器执行的顺序就是从最后一个装饰器开始,执行到第一个装饰器,再执行函数本身。
1
2
3
转载地址:http://zxtmi.baihongyu.com/