一,装饰器本质
闭包函数
功能:就是在不改变原函数调用方式的情况下,在这个函数前后加上扩展功能
作用:解耦,尽量的让代码分离,小功能之前的分离。
解耦目的,提高代码的重用性
二,设计模式
开放封闭原则
*对扩展是开放的
*对修改是封闭的
三,代码解释
*通用代码
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 def timmer(func): #---> jjj 5 def inner(*args,**kwargs): 6 ret = func(*args,**kwargs) # --->ret = jjj() 7 # print('没有返回值的调用') 8 return ret 9 return inner 10 11 @timmer #jjj = timmer(jjj) 语法糖 12 def jjj(): 13 return 123 14 # jjj() #调用函数,如果被装饰的函数有返回值,就需要下边的代码 15 ret = jjj() #==>inner 有返回值 16 print(ret) #返回123
执行顺序
*用装饰器简单实现用户登录,登陆一个函数成功,无需再次登陆
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 tag = False 5 6 def login(func): 7 def inner(*args,**kwargs): 8 global tag 9 if tag == False: 10 user = input('please your username>>>:') 11 pwd = input('please your password>>>:') 12 f = open('aaa','r',encoding='utf-8') 13 for i in f: 14 user_pwd = eval(i) 15 if user == user_pwd['name'] and pwd == user_pwd['password']: 16 tag = True 17 f.close() 18 if tag: 19 ret = func(*args,**kwargs) 20 return ret 21 return inner 22 23 @login 24 def haha(*args,**kwargs): 25 print('中国动漫') 26 pass 27 28 @login 29 def hengheng(*args,**kwargs): 30 print('美国动漫') 31 pass 32 ##########用户调用方式 33 haha() 34 hengheng()
*统计函数中有多少个函数被装饰了
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 l = [] 5 def wrapper(func): 6 #l.append(func) #统计当前程序中有多少个函数被装饰了 7 def inner(*args,**kwargs): 8 l.append(func) #统计本次程序执行有多少个带这个装饰器的函数被调用了 9 ret = func(*args,**kwargs) 10 return ret 11 return inner 12 13 @wrapper #f1 = wrapper(f1) 14 def f1(): 15 print('in f1') 16 17 @wrapper #f2 = wrapper(f2) 18 def f2(): 19 print('in f2') 20 21 @wrapper #f2 = wrapper(f2) 22 def f3(): 23 print('in f3') 24 f1() 25 f2() 26 f3() 27 28 print(len(l))
四,双层带参数的装饰器
顾名思义,就是给装饰器添加参数
可以控制被装饰的函数是否需要这个装饰器,或者其他用法
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 #带参数的装饰器 开关 ,控制是否需要装饰器 5 6 F = False #通过这里控制是否需要装饰器 7 def outer(flag): 8 #以下是装饰器 9 def wrapper(func): 10 def inner(*args,**kwargs): 11 if flag: 12 print('before') #被装饰代码运行之前 13 ret = func(*args,**kwargs) #被装饰的代码 14 print('after') #被装饰代码运行之后 15 else: 16 ret = func(*args, **kwargs) 17 return ret 18 return inner 19 ########################### 20 return wrapper 21 22 @outer(F) # F默认是FALSE,那么装饰器没有用上,因为 if false: ret = func(),因为加了括号直接执行,返回了wrapper,后面就是装饰器过程了 23 def hahaha(): 24 print('hahaha') 25 26 @outer(F) # F如果是TRUE,就用上了装饰器 27 def shuangww(): 28 print('shuangwaiwai') 29 30 shuangww() 31 hahaha()
执行过程
五,多个装饰器装饰一个函数(非重点)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 #多个装饰器装饰一个函数 5 def qqxing(func): #func = pipixia_inner 6 def qqxing_inner(*args,**kwargs): 7 print('in qqxing:before') 8 ret = func(*args,**kwargs) #pipixia_inner 9 print('in qqxing:after') 10 return ret 11 return qqxing_inner 12 13 def pipixia(func): #dapangxie 14 def pipixia_inner(*args,**kwargs): 15 print('in pipixia:before') 16 ret = func(*args,**kwargs) #dapangxie 17 print('in pipixia:after') 18 return ret 19 return pipixia_inner 20 21 #qqxing(pipixia_inner) -->dapangxie = qqxing_inner() 22 @qqxing #dapangxie = qqxing(dapangxie) -->dapangxie = qqxing(pipixia(dapangxie)) --> 23 @pipixia #dapangxie = pipixia(dapangxie) 24 def dapangxie(): 25 print("饿了么") 26 dapangxie() 27 28 #dapangxie = pipixia(dapangxie) 29 #dapangxie = qqxing(dapangxie) -->dapangxie = qqxing(pipixia(dapangxie)) 30 #pipixia(dapangxie) == >pipixia_inner 31 #qqxing(pipixia_inner) = qqxing_inner 32 #dapangxie() ==> qqxing_inner()