python之路15--装饰器-all
一、装饰器说明
1、装饰器的作用:
在不改变原来函数的调用方式的情况下 在这个函数的前后添加新的功能
2、装饰器完美的符合了开放封闭的开发原则,
对扩展是开发的
对修改是封闭的
3、装饰器与闭包函数的区别
闭包函数不一定是装饰器
装饰器函数一定是闭包函数
二、装饰器的语法
1、写一个计算一个函数执行时间的基础装饰器
import time def budao(): #1、定义执行函数 time.sleep(0.01) print("welcome to budaozhe.co") def budaozhe(f): #2、定义装饰器函数(f)为形参接收budao的内存地址 def vip(): #4、定义了函数里的函数 start = time.time() f() end = time.time() print(end - start) return vip #5、将自己的内存地址作为返回值 budao = budaozhe(budao) #3、执行budaozhe函数并将budao函数的内存地址传给budaozhe函数的形参并接收返回值vip(即此时budaob变量是函数vip的内存地址) budao() #此时执行的是vip函数
执行结果:
welcome to budaozhe.co
0.01099395751953125
画图说明:

2、装饰器的语法糖写法与带参数函数的装饰器
import time def budaozhe(f): #定义装饰器函数 def vip(a): #4、定义了函数里的函数 start = time.time() ret = f(a) end = time.time() print(end - start) return ret return vip #5、将自己的内存地址作为返回值 @budaozhe #语法糖的写法:它的位置必须紧挨着被装饰的函数,@装饰器函数,最终执行的意思是:budao = budaozhe(budao) def budao(a): #被装饰的函数,带有形参 time.sleep(0.01) print("welcome to budaozhe.co",a) return "huanying" a = budao(1) #此时执行的是vip函数 print(a)
执行结果:
welcome to budaozhe.co 1
0.01002049446105957
huanying
画图说明:

3、装饰带多个位置参数和关键字参数函数的装饰器
import time def budaozhe(f): #定义装饰器函数 def vip(*args,**kwargs): #4、定义了函数里的函数 start = time.time() ret = f(*args,**kwargs) end = time.time() print(end - start) return ret return vip #5、将自己的内存地址作为返回值 @budaozhe #语法糖的写法:它的位置必须紧挨着被装饰的函数,@装饰器函数,最终执行的意思是:budao = budaozhe(budao) def budao(a,b): #被装饰的函数 time.sleep(0.01) print("welcome to budaozhe.co",a,b) return "huanying" @budaozhe #语法糖的写法:它的位置必须紧挨着被装饰的函数,@装饰器函数,最终执行的意思是:budao = budaozhe(budao) def budao1(a): #被装饰的函数 time.sleep(0.01) print("welcome to budaozhe.co",a) return "huanying" #budao = budaozhe(budao) #3、执行budaozhe函数并将budao函数的内存地址传给budaozhe函数的形参并接收返回值vip(即此时budaob变量是函数vip的内存地址) a = budao1(1) #此时执行的是vip函数 a1 = budao(1,b = 2) #此时执行的是vip函数 print(a,'分割符',a1)
执行结果:
welcome to budaozhe.co 1 0.010038375854492188 welcome to budaozhe.co 1 2 0.010995149612426758 huanying 分割符 huanying
画图说明:

4、wraps使用
前面写的几个函数虽然调用方式还是和之前的调用方式一样,但是实际步骤还是走了装饰器的媒介,下面看下使用wraps实现原函数和装饰的功能互不影响的方法
from functools import wraps def wrapper(func): @wraps(func) #@wraps为固定格式,(func)为wrapper传进来的 def inner(*args,**kwargs): print("装饰之前做的事") ret = func(*args,**kwargs) print('装饰之后做的事') return ret return inner @wrapper #holiday = wrapper(holiday) def holiday(day): ''' 这是一个放假通知 ''' print('全体放假%s天' %day) return '好开心' print(holiday.__name__) #结果为:holiday print(holiday.__doc__) #结果为:这是一个放假通知 ret = holiday(3) #结果为:全体放假3天 print(ret) #结果为:好开心
执行结果:
holiday
这是一个放假通知
装饰之前做的事
全体放假3天
装饰之后做的事
好开心
画图说明:

5、带参数的装饰器
装饰器最多只能三层函数嵌套
实现需求说明:
多个函数,再需要的时候开启装饰器,不需要时关闭装饰器,
import time FLAGE = True def wrapper_out(flag): def wrapper(func): def inner(*args,**kwargs): if flag == True: start = time.time() ret = func(*args,**kwargs) end = time.time() print(end - start) return ret else: ret = func(*args,**kwargs) return ret return inner return wrapper @wrapper_out(FLAGE) def yisou1(): print("welcome to www.yisou.co") time.sleep(0.2) @wrapper_out(FLAGE) def yisou2(): print("上易搜,了解每天新鲜事") time.sleep(0.2) yisou1() yisou2()
执行结果:
welcome to www.yisou.co 0.2008812427520752 上易搜,了解每天新鲜事 0.20087575912475586
画图说明:

6、多个装饰器装饰同一个函数
def wrapper1(f): def inner1(): print("wrapper1 function frond") f() print("wrapper1 function end") return inner1 def wrapper2(f): def inner2(): print("wrapper2 function frond") f() print("wrapper2 function end") return inner2 @wrapper2 @wrapper1 #func = wrapper1(func) def func(): print("this is function") func()
执行结果:
wrapper2 function frond wrapper1 function frond this is function wrapper1 function end wrapper2 function end
画图说明:


浙公网安备 33010602011771号