12.装饰器
装饰器的形成过程
import time def timmer(f): #装饰器函数 def inner(): start=time.time() f() #被装饰的函数 end=time.time() print(start-end) return inner def func(): time.sleep(0.1) print('老板同时大家好') func=timmer(func) func()
f是一个局部变量,在函数timmer()执行完成后就会消失,但是被函数inner()引用,这里就形成一个闭包,因此装饰器的本质就是闭包函数。
在以上代码中func=timmer(func) ,由于函数timmer()返回值是inner,所以等价于func=inner ,最后func()就等价于inner(),相当于直接执行了函数inner()
而函数inner()中包含func()函数和其他语句,就相当于对函数func()的功能进行拓展,对函数func进行修饰。
以上代码也可以写成
import time def timmer(f): #装饰器函数 def inner(): start=time.time() f() #被装饰的函数 end=time.time() print(start-end) return inner @timmer def func(): time.sleep(0.1) print('老板同时大家好') func()
这里是装饰器函数的正常写用方法,函数timmer是装饰器函数,对函数func()有装饰作用,使用装饰器是被写成@timmer ,给被装饰的函数的加上这个,函数等价于func=timmer(func),通常的写法是@+装饰器函数名,同时这种类似的使用方法被称为语法糖,可以简化代码,方便使用。
函数f()是被装饰的函数,这段代码中也就是函数func()。
装饰器的作用
不想修改函数的内容和调用方式,在原来的函数前后添加功能
装饰器遵循的原则
开放封闭原则
开放:对拓展是开放的
封闭:对修改是封闭的
带参数和返回值的装饰器函数
import time def timmer(f): #装饰器函数 def inner(*args,**kwargs): start=time.time() ret = f(*args,**kwargs) #被装饰的函数 end=time.time() print(start-end) return ret return inner @timmer def func(a,b): time.sleep(0.1) print('老板同时大家好',a,b) return '新年好' @timmer def func1(a,b=1): time.sleep(0.1) print('老板同时大家好',a,b) return '新年好' func() func1()
如上代码,不确定装饰器函数的参数类型和数量时,可以使用动态参数*args和**kwargs
同时,功能函数几乎都是有返回值的,应该在装饰器函数内接受被装饰函数的返回值并返回。
装饰器的固定模式(必背)
def timmer(f): #装饰器函数,f是被装饰的函数 def inner(*args,**kwargs): ‘在被装饰函数之前要做的事’ ret = f(*args,**kwargs) #被装饰的函数,ret接受函数f的返回值 ‘在被装饰函数之后要做的事’ return ret return inner
@timmer 不使用该方法的话,可以使用 func=timmer(func) 代替该语法
def func():
print("hello")
return 'a'
ret=func() #表面上是使用func(),但是在使用装饰器函数后,实际上是在使用内部函数inner
#ret 接受函数func()的返回值

浙公网安备 33010602011771号