装饰器的模板:
import time
def func1(): start = tiime.time() print('in func1') end = time.time() print(end-start) func1()
来公司半年,写了2000+函数,挨个改一遍,1个礼拜过去了,等领导审核完,再挨个给删了。。。又1个礼拜过去了。。。这是不是很闹心?
import time def timer(func): start = time.time() func() print(time.time() - start) def func1(): print('in func1') def func2(): print('in func2') timer(func1) timer(func2)
这样看起来是不是简单多啦?不管我们写了多少个函数都可以调用这个计时函数来计算函数的执行时间了。。。尽管现在修改成本已经变得很小很小了,但是对于同事来说还是改变了这个函数的调用方式,假如某同事因为相信你,在他的代码里用你的方法用了2w多次,那他修改完代码你们友谊的小船也就彻底地翻了。
你要做的就是,让你的同事依然调用func1,但是能实现调用timer方法的效果。
import time def timer(func): start = time.time() func() end = time.time() prinet(end- start) def func1(): print('in func1') func1 = timer func1
非常可惜,上面这段代码是会报错的,因为timer方法需要传递一个func参数,我们不能在赋值的时候传参,因为只要执行func1 = timer(func1),timer方法就直接执行了,下面的那句func1根本就没有意义。到这里,我们的思路好像陷入了僵局。。。
装饰器的形成过程
import time def func1(): print('in func1') def timer(func): def inner(): start = time.time() func() end = time.time() print(end - start) func1 = timer(func1) func1()
语法糖:
装饰器的本质:一个闭包函数
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
import time def timer(func): def inner(): start = time.time() func() end = time.time() print(end - start) @timer def func1(): print('in func1') func1()
带参装饰器:
import time def timer(func): def inner(a): start = time.time() print(a) end = time.time() return inner @timer def func1(a): print(a) func1(1)
import time #装饰器 # def timer(f1): # # def inner(): # # start_time = time.time() # # f1() # # end_time = time.time() # # print('此函数的执行效率%s' %(end_time-start_time)) # # return inner # # # # @timer #func1 = timer(func1) # # def func1(): # # print('晚上回去吃烧烤') # # time.sleep(0.3) # # func1() #完整装饰器 # def wrapper(f1): # def inner(*args,**kwargs): # ret=f1(*args,**kwargs) # return ret # return f1 # @wrapper # def func1(): # print(222) # print(333) # print(func1()) # import time # def timer(func): # def inner(a): # start = time.time() # print(a) # end = time.time() # return inner # @timer # def func1(a): # print(a) # func1(1) def timer(func): def inner(*args,**kwargs): start = time.time() re = func(*args,**kwargs) end = time.time() print(end - start) return re return inner def func1(a,b): print('in func1') def func2(a): print('in func2 and get a:%s'%(a)) return 'fun2 over' func1('aaa','aaaaaa') func2 = func2('bbbbbbb') print(func2)
带返回值的--装饰器
import time def timer(func): def inner(*args,**kwargs): start = time.time() re = func(*args,**kwargs) print(time.time() - start) return re return inner @timer #==> func2 = timer(func2) def func2(a): print('in func2 and get a:%s'%(a)) return 'fun2 over' func2('bbbbbbb') print(func2('aaaaaa'))
from functools import wraps def deco(func): @wraps(func) #加在最内层函数正上方 def wrapper(*args,**kwargs): return func(*args,**kwargs) return wrapper @deco def index(): '''哈哈哈哈''' print('from index') print(index.__doc__) print(index.__name__)