一,装饰器本质
闭包函数
功能:就是在不改变原函数调用方式的情况下,在这个函数前后加上扩展功能
作用:解耦,尽量的让代码分离,小功能之前的分离。
解耦目的,提高代码的重用性
二,设计模式
开放封闭原则
*对扩展是开放的
*对修改是封闭的
三,代码解释
*通用代码
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 inner10 11 @timmer #jjj = timmer(jjj) 语法糖12 def jjj():13 return 12314 # 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 = True17 f.close()18 if tag:19 ret = func(*args,**kwargs)20 return ret21 return inner22 23 @login24 def haha(*args,**kwargs):25 print('中国动漫')26 pass27 28 @login29 def hengheng(*args,**kwargs):30 print('美国动漫')31 pass32 ##########用户调用方式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 ret11 return inner12 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 ret18 return inner19 ###########################20 return wrapper21 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 ret11 return qqxing_inner12 13 def pipixia(func): #dapangxie14 def pipixia_inner(*args,**kwargs):15 print('in pipixia:before')16 ret = func(*args,**kwargs) #dapangxie17 print('in pipixia:after')18 return ret19 return pipixia_inner20 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_inner31 #qqxing(pipixia_inner) = qqxing_inner32 #dapangxie() ==> qqxing_inner()