装饰器作用:
原则:开放封闭原则
对扩展是开放
对修改是封闭
装饰器固定模式
def timmer(f):#装饰器函数
def inner():#闭包,内部函数调用外部的变量
start = time.time()
f() #被装饰函数
end = time.time()
print(end-start)
return inner
@timmer
def func():
time.sleep(0.01)
print("hello")
#func= timmer(func)
func()
#不想修改函数的调用方式,但是想在原函数前后添加功能
如果函数有返回值和参数inner函数也要相应改变,可以把inner的参数写为万能参数(*args,**kwargs)
语法糖
用了之后代码便捷简单
@timmer
在被装饰的函数上面紧邻着写@装饰器函数名字
如@timmer,就相当于写了func=timmer(func)没有语法糖就需要人为加上这句
def timmer(f):#装饰器函数
def inner(*args,**kwargs):
ret = f(*args,**kwargs) #被装饰的函数
return ret
return inner
@timmer #语法糖,@装饰器函数名
def func(*args,**kwargs):#被装饰函数
time.sleep(0.01)
print("hello:)
func(a,b,f=1)#例子
装饰器的英文是wrappper
带参数的装饰器:
import time
FLAG = True
def timmer_out(flag):
def timmer(f):#装饰器函数
def inner(*args,**kwargs):
if flag:
加的模块功能
ret = f(*args,**kwargs) #被装饰的函数
加的功能
return ret
else:
ret = f(*args,**kwargs) #被装饰的函数
return ret
return inner
return timmer
@timmer_out(FLAG)#这个地方把@和后面的分开看,timmer_out(FLAG)返回的是timmer ,相当于@timmer
def func(*args,**kwargs):
print("hahahhaahhhh")
多个装饰器装饰一个函数
def wrapper1(func):
def inner():
print('wrapper1,before func')
func()
print('wrapper1,after func')
return inner
def wrapper2(func):
def inner():
print('wrapper2,before func')
func()
print('wrapper2,after func')
return inner
@wrapper2
@wrapper1
def f():
print('in f')
运行结果是:
wrapper2,before func
wrapper1,before func
in f
wrapper1,after func
wrapper2,after func
被装饰函数有返回值的情况