python--装饰器
为什么要有装饰器?
开放封闭原则:对修改封闭,对扩展开放
什么是装饰器?
装饰器是可调用的函数,被装饰者也是可以调用的函数
原则:不修改被装饰者的代码,不改变被装饰者的调用方式
目的:给被装饰者添加功能
实现过程
1 #原始index函数 2 import time 3 def index(): 4 time.sleep(3) 5 print('贼溜') 6 return '大牛' 7 8 #为index函数添加功能 9 strat_time = time.time() 10 index() 11 end_time = time.time() 12 print(end_time - strat_time) 13 14 #上述添加过程在为其他函数添加功能时,需要重复写代码,改进如下 15 def wrapper(): 16 strat_time = time.time() 17 index() 18 end_time = time.time() 19 print(end_time - strat_time) 20 wrapper() 21 22 #上述改进过程,只能为index()添加功能,而且改变了index的调用方式,改进如下 23 def timmer(func): 24 def wrapper(): 25 strat_time = time.time() 26 res=func() 27 end_time = time.time() 28 print(end_time - strat_time) 29 return res 30 return wrapper 31 index=timmer(index) #闭包函数的概念---timmer(index)实际上就是调用了一个带有func=index参数的wrapper() 32 33 #改进依然不完美,当传入的函数带有参数时,程序报错,改进如下 34 def timmer(func): 35 def wrapper(*args,**kwargs): 36 strat_time = time.time() 37 res=func(*args,**kwargs) 38 end_time = time.time() 39 print(end_time - strat_time) 40 return res 41 return wrapper 42 #至此,装饰器完成,得到如下模板 43 def outter(func): 44 def wrapper(*args,**kwargs): 45 res = func(*args,**kwargs) 46 return res 47 return wrapper 48 #任何装饰器都可以套用此模板
基本语法
@deco1 @deco2 @deco3 def foo(): pass foo =deco1(deco2(deco3(foo))) foo()是需要被装饰的函数
无参装饰器
import time def timmer(func): def wrapper(*args,**kwargs): #wrapper()为闭包函数 start_time=time.time() res=func(*args,**kwargs) stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return res return wrapper #timmer()的返回值指向函数wrapper()的内存地址 @timmer def foo(): time.sleep(3) print('from foo') foo()
有参装饰器
def auth(driver='file'):#此处可以添加任意参数,所有有参装饰器最多三层即可 def auth2(func): #此处的func固定,不允许添加值,只能是被装饰函数的内存地址 def wrapper(*args,**kwargs):#此处不允许修改,一旦修改,则程序在装饰有参函数和无参函数时,其中一个肯定报错 name=input("user: ") pwd=input("pwd: ") if driver == 'file':#作用域知识,本层找不到,往外部找 if name == 'egon' and pwd == '123': print('login successful') res=func(*args,**kwargs) return res elif driver == 'ldap': print('ldap') return wrapper return auth2 @auth(driver='file') def foo(name): print(name) res = auth(driver='file') print(res) foo('egon')