装饰器
1,什么是装饰器
装饰器是一个用来为被装饰者添加功能的工具 被装饰者:函数 装饰器:可以用函数实现装饰器这种工具
2,为何要用装饰器
为了在不修改被装饰器对象源代码以及调用方式的前提下 为被装饰对象添加上新功能
3,如何用装饰器
#被装饰对象 def index(x): print('kjadha %s'% x) index(111) #方案1 :修改了源代码 import time def index(x): start= time.time() print('kjadha %s'% x) time.sleep(3) stop = time.time() print(stop - strat) index(111) #方案2:没有修改源代码与调用方式,但是有了代码冗余 import time def index(x): print('kjadha %s'% x) time.sleep(3) start= time.time() index(111) stop = time.time() print(stop - strat) #方案3:修改了源代码的调用方式 wrapper函数需要外部传入参数 import time def index(x): print('kjadha %s'% x) time.sleep(3) def wrapper(): start= time.time() index(111) stop = time.time() print(stop - strat) wrapper() 方案五:闭包函数 import time def index(x): print('kjadha %s'% x) time.sleep(3) def outter(func): def wrapper(*args,**kwargs): start= time.time() func(*args,**kwargs) stop = time.time() print(stop - strat) return wrapper index = outter(index) #index =wrapper内存地址 index(111) #wrapper(111) 方案六 :把wrapper伪装成被装饰对象一样 import time def index(x): print('kjadha %s'% x) time.sleep(3) retrun 777 def outter(func): def wrapper(*args,**kwargs): start= time.time() res = func(*args,**kwargs) stop = time.time() print(stop - strat) return res return wrapper index = outter(index) #index =wrapper内存地址 index(111) #wrapper(111)
装饰器的实现
函数装饰器分为两种,无参装饰器和有参装饰器
两者的实现原理一样,都是‘函数嵌套+闭包+函数对象’的组合使用产物。
语法糖
# @后面跟函数名 import time def outter(fun): @wraps(func) def wrapper(*args,**kwargs): start = time.time() res = fun(*args,**kwargs) stop = time.time() print(stop - start) return res # wrapper.__doc__ = index.__doc__ # wrapper.__name__ = index.__name__ return wrapper @outter #index = outter(index内存地址) def index(x): ''' joiqwujaerohjqopw ''' print('na %s'% x) time.sleep(3) return 777 res = index(111) print(res) #语法糖装饰器运行顺序至上而下,调用方式至下而上,如下 函数 = 装饰器函数的内存地址 @语法糖1 #1(装饰器2的内存地址)-》装饰器函数1的内存地址 @语法糖2 #2(装饰器3的内存地址)-》装饰器函数2的内存地址 @语法糖3 #3(函数的内存地址)-》装饰器函数3的内存地址