python学习day11 day12 装饰器
装饰器是一种特殊的闭包,它是嵌套函数,也调用了外部函数的变量,只不是调用的是外部函数的形参。
用于装饰函数
装饰器的作用 —— 不想修改函数的调用方式 但是还想在原来的函数前后添加功能
timmer就是一个装饰器函数,只是对一个函数 有一些装饰作用
原则: 开放封闭原则
开放 : 对扩展是开放的
封闭 : 对修改是封闭的
装饰器的固定模式:
def wrapper(f): #装饰器函数,参数为被装饰的函数 def inner(*args,**kwargs): #参数为被装饰函数的原始参数 '''在被装饰函数之前要做的事''' ret = f(*args,**kwargs) #被装饰的函数,ret是被装饰函数的返回值 '''在被装饰函数之后要做的事''' return ret #返回inner中的值 也就是装饰后的东西 return inner #返回inner的名字 @wrapper #语法糖 @装饰器函数名 def func(a,b): #被装饰的函数 time.sleep(0.01) print('老板好同事好大家好',a,b) return '新年好'
ret = func(1,2) #实际上执行的是inner(1,2) 也就是装饰后的函数
应用:
自定义函数func的执行时间+0.01s
import time def wapper(f): #定义一个装饰器 def inner(*args,**kwargs): start = time.time() ret = f(*args,**kwargs) end = time.time() t = end - start return ret, t return inner @wapper def func(a,b='zepei'): c = 70 + a return b,c print(func(2,b='fan')) #(('fan', 72), 0.010000228881835938)
装饰器进阶
wraps
from functools import wraps def wrapper(func): #func = holiday @wraps(func) 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__) # 加了wraps后 此处打印的是holiday的名字 print(holiday.__doc__) # 打印holiday的解释文档 ret = holiday(3) #inner print(ret)
带参数的装饰器
外面再加入一个嵌套,判断是否使用装饰器
import time FLAGE = False #如果是False 不装饰函数 def timmer_out(flag): def timmer(func): def inner(*args,**kwargs): if flag: 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 timmer # timmer = timmer_out(FLAGE) @timmer_out(FLAGE) #wahaha = timmer(wahaha) def wahaha(): time.sleep(0.1) print('wahahahahahaha') @timmer_out(FLAGE) def erguotou(): time.sleep(0.1) print('erguotoutoutou') wahaha() erguotou()
多个装饰器装饰一个函数
两个装饰器详解:
三个装饰器:
def wrapper1(func): def inner1(): print('wrapper1 ,before func') ret = func() #func=f print('wrapper1 ,after func') return ret return inner1 def wrapper2(func): def inner2(): print('wrapper2 ,before func') ret = func() #func=inner1 print('wrapper2 ,after func') return ret return inner2 def wrapper3(func): def inner3(): print('wrapper3 ,before func') ret = func() #func=inner2 print('wrapper3 ,after func') return ret return inner3 @wrapper3 # f=wrapper3(f)=wrapper3(inner2)=inner3 @wrapper2 # f=wrapper2(f)=wrapper2(inner1)=inner2 @wrapper1 # 先执行这个语法糖 f=wrapper1(f)=inner1 def f(): print('in f') return '哈哈哈' f() # inner3() ''' 输出: wrapper3 ,before func wrapper2 ,before func wrapper1 ,before func in f wrapper1 ,after func wrapper2 ,after func wrapper3 ,after func ''' #如果执行下面的,会打印f的输出 print(f()) ''' 输出: wrapper3 ,before func wrapper2 ,before func wrapper1 ,before func in f wrapper1 ,after func wrapper2 ,after func wrapper3 ,after func 哈哈哈 '''