装饰器形成的过程
装饰器的作用:不想修改函数的调用方式,但是还想在原来的函数前后加功能
原则:开发封闭原则
开发:对扩展是开发的
封闭:对修改是封闭的
装饰器的固定模式
计算运行时间
1 import time 2 # time.time()获取当前时间 3 # time.sleep(5)让程序在执行到这个位置的时候停一会儿 4 5 6 def timer(f):#func地址 ;装饰器函数 7 #闭包 8 def inner(): 9 start=time.time() 10 ret=f()#被装饰的函数 11 end=time.time() 12 print(end-start) 13 return ret 14 return inner 15 @timer #语法糖 @装饰器函数名 16 # func=timer(func)#就等于@timer 17 def func():#被装饰的函数 18 # start=time.time() 19 print(1) 20 time.sleep(0.01) 21 # end=time.time() 22 # print(end-start) 23 return '新年好' 24 ret=func()#实际执行的是inner 25 print(ret)
timer就是一个装饰器函数,只是对一个函数有装饰作用
装饰带参数函数的装饰器
1 #装饰带参数函数的装饰器 2 import time 3 def timer(f):#func地址 ;装饰器函数 4 #闭包 5 def inner(*args): 6 start=time.time() 7 ret=f(*args)#被装饰的函数 8 end=time.time() 9 print(end-start) 10 return ret 11 return inner 12 @timer #语法糖 @装饰器函数名 13 def func(a):#被装饰的函数 14 print(1,a) 15 time.sleep(0.01) 16 return '新年好' 17 @timer #语法糖 @装饰器函数名 18 def func1(a,b):#被装饰的函数 19 print(1,a,b) 20 time.sleep(0.01) 21 return '新年好' 22 23 ret=func1(1,2)#实际执行的是inner 24 ret1=func(1) 25 #func()#实际执行的是inner 26 print(ret) 27 print(ret1)
固定格式
def wrapper(f):#f被装饰的函数,wrapper就是装饰def inner(*args,**kwargs):#定义一个其他函数#在被装饰函数之前要做的事ret=f(*args,**kwargs)#被装饰的函数,被装饰的函数执行#在被装饰函数之后要做的事return retreturn inner#不加() @wrapper #语法糖 @装饰器函数名 def func1(a,b):#被装饰的函数time.sleep(0.01)print(1,a,b)return '新年好'
装饰器进阶
1 def wrapper(func): #func = holiday 2 def inner(*args,**kwargs): 3 print('在被装饰的函数执行之前做的事') 4 ret = func(*args,**kwargs) 5 print('在被装饰的函数执行之后做的事') 6 return ret 7 return inner 8 9 @wrapper #holiday = wrapper(holiday) 10 def holiday(day): 11 '''这是一个放假通知''' 12 print('全体放假%s天'%day) 13 return '好开心' 14 15 print(holiday.__name__)
1 # 装饰器进阶 2 # functools wraps 3 from functools import wraps 4 def wrapper(func):#f被装饰的函数,wrapper就是装饰 5 @wraps(func)# 6 def inner(*args,**kwargs): 7 print('在被装饰的函数执行之前做的事') 8 ret = func(*args,**kwargs) 9 print('在被装饰的函数执行之后做的事') 10 return ret 11 return inner 12 @wrapper #语法糖 @装饰器函数名 13 def holiday(day): 14 '''这是一个放假通知''' 15 print('全体放假%s天'%day) 16 return '好开心' 17 print(holiday.__name__) 18 print(holiday.__doc__) 19 ret = holiday(3) #inner 20 print(ret) 21 #带参数的装饰器 22 # 多个装饰器装饰同一个函数 23 24 # 函数名.__name__查看字符串格式的函数名 25 # 函数名.__name__#document查看函数的注释
1 #带参数的装饰器 2 #500个函数 3 import time 4 FLAGE = False 5 def timmer_out(flag): 6 def timmer(func): 7 def inner(*args,**kwargs): 8 if flag: 9 start = time.time() 10 ret = func(*args,**kwargs) 11 end = time.time() 12 print(end-start) 13 return ret 14 else: 15 ret = func(*args, **kwargs) 16 return ret 17 return inner 18 return timmer 19 # timmer = timmer_out(FLAGE) 20 @timmer_out(FLAGE) #@timer #wahaha = timmer(wahaha) 21 def wahaha(): 22 time.sleep(0.1) 23 print('wahahahahahaha') 24 25 @timmer_out(FLAGE) 26 def erguotou(): 27 time.sleep(0.1) 28 print('erguotoutoutou') 29 wahaha() 30 erguotou()
#多个装饰器装饰一个函数 def wrapper1(func):def inner1():print('wrapper1 ,before func')ret = func()print('wrapper1 ,after func')return retreturn inner1def wrapper2(func):def inner2():print('wrapper2 ,before func')ret = func()print('wrapper2 ,after func')return retreturn inner2def wrapper3(func):def inner3():print('wrapper3 ,before func')ret = func()print('wrapper3 ,after func')return retreturn inner3@wrapper3 @wrapper2 @wrapper1 def f():print('in f')return '哈哈哈'print(f())#记录用户的登录情况 #计算这个函数的执行时间