week4-python之装饰器
装饰器原则
装饰器的遵循的原则:1 不修改被装饰对象的源代码
2 不修改被调用对象的调用方式
装饰器的目的是:在遵循1和2原则的前提,为其他新功能函数添加
开放封闭原则:对扩展是开放的,对修改是封闭
装饰器本身可以是任意可调用对象,被装饰的对象本身也可以是任意可调用对象
用装饰器给原始函数添加一个执行时间功能,举例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import time #导入系统内置time模块 #第一步 2 3 def index(): #定义一个index原始函数,之后用装饰器添加它的运行时间功能 #第二步 4 time.sleep(3) #第十一步 5 print("welcome to index") #第十二步 6 7 def timmer(): #定义一个timmer函数 #第三步 8 func=index #把func指向index函数名称,局部名称空间,可以用于实现下面的闭包函数 #第五步 9 def wrapper(): #定义wrapper 闭包函数名 #第六步 10 start=time.time() #开始计时 #第九步 11 func() #等于执行了 index() #第十步 12 stop=time.time()#计时结束 #第十三步 13 print('run time is %s' %(stop-start))#开始时间减去结束时间等于运行时间 #第十四步 14 return wrapper #返回wrapper的执行结果(index函数的执行运行时间)给timmer函数 #第七步 15 index=timmer() #装饰器的原则之一是不改变函数的调用方法,所以定义一个新的index指向timmer #第四步 16 index() #执行index 这时已经给原始的index函数加上了 运行时间的功能 #第八步
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import time 2 def index(): 3 time.sleep(3) 4 print('welcome to home page') 5 def home(): 6 time.sleep(2) 7 print('welcome to home page') 8 def timmer(func): 9 def wrapper(): 10 start=time.time() 11 func() 12 stop=time.time() 13 print('run time is %s' %(stop-start)) 14 return wrapper 15 index=timmer(index) 16 home=timmer(home) 17 index() 18 home()
装饰器的@用法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import time 2 def timmer(func): 3 def wrapper(): 4 start=time.time() 5 func() 6 stop=time.time() 7 print('run time is %s' %(stop-start)) 8 return wrapper 9 @timmer #index=timmer(index) 10 def index(): 11 time.sleep(3) 12 print('welcome to index') 13 @timmer #index=timmer(home) 14 def home(): 15 time.sleep(2) 16 print('welcome to home page') 17 index() 18 home()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import time #第一步 2 def timmer(func): #第二步 3 def wrapper(*args,**kwargs): #第四步 #第七步 4 start=time.time() #第十步 第十八步 5 res=func(*args,**kwargs) #第十一步 第十九步 6 stop=time.time() #第十四步 第二十三步 7 print('run time is %s' %(stop-start)) # 第十五步 第二十四步 8 return res #第十六步 第二十五步 9 return wrapper #第五步 #第八步 10 @timmer #index=timmer(index) 第三步 11 def index(name): 12 time.sleep(3) #第二十步 13 print('welcome to index') #第二十一步 14 return 123 #第二十二步 15 @timmer #home=timmer(home) #第六步 16 def home(name): 17 time.sleep(2) #第十二步 18 print('webcome %s to home page' %name) #第十三步 19 res1=home('warren') #第九步 20 res2=index('xwm') #第十七步 21 print(res1) # 第二十六步 22 print("##########") #第二十七步 23 print(res2) #第二十八步
无参装饰器版本
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #db.txt{"a":"123","b":"456"} 2 current_user={'user':None} 3 def auth(func): 4 def wrapper(*args,**kwargs): 5 if current_user['user']: 6 return func(*args,**kwargs) 7 name=input('name: ').strip() 8 password=input('password: ').strip() 9 with open('db.txt',encoding='utf-8') as f: 10 user_dic=eval(f.read()) 11 if name in user_dic and password == user_dic[name]: 12 res=func(*args,**kwargs) 13 current_user['user']=name 14 return res 15 else: 16 print('user or password error') 17 return wrapper 18 @auth #index=auth(index) index=wrapper 19 def index(): 20 print('from index') 21 index() 22 @auth 23 def home(name): 24 print('welcome %s' %name) 25 index() #wrapper() 26 home('a')
有参装饰器版本
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 current_user={'user':None} 2 def auth(auth_type='file'): 3 def deco(func): 4 def wrapper(*args, **kwargs): 5 if auth_type == 'file': 6 if current_user['user']: 7 return func(*args, **kwargs) 8 name = input('name: ').strip() 9 password = input('password: ').strip() 10 11 with open('db.txt', encoding='utf-8') as f: 12 user_dic = eval(f.read()) 13 if name in user_dic and password == user_dic[name]: 14 res = func(*args, **kwargs) 15 current_user['user'] = name 16 return res 17 else: 18 print('user or password error') 19 elif auth_type == 'mysql': 20 print('mysql') 21 22 elif auth_type == 'ldap': 23 print('ldap') 24 else: 25 print('not valid auth_type') 26 return wrapper 27 return deco 28 @auth(auth_type='mysql') #@deco #index=deco(index) 29 def index(): 30 print('from index') 31 @auth(auth_type='file') 32 def home(name): 33 print('welcome %s' %name) 34 index() #wrapper() 35 home('a')
装饰器wraps使用,可以查看原始函数的注释
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import time from functools import wraps def timmer(func): @wraps(func) def wrapper(*args,**kwargs): start=time.time() res=func(*args,**kwargs) stop=time.time() print('run time is %s' %(stop-start)) return res return wrapper @timmer # index=timmer(index) def index(): '''这是index函数''' time.sleep(3) print('welcome to index') return 123 print(index.__doc__) # print(help(index))
一个函数头顶上可以多个装饰器,上面的先生效
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import time 2 from functools import wraps 3 current_user={'user':None} 4 5 def timmer(func): 6 @wraps(func) 7 def wrapper(*args,**kwargs): 8 start=time.time() 9 res=func(*args,**kwargs) 10 stop=time.time() 11 print('run time is %s' %(stop-start)) 12 return res 13 return wrapper 14 def auth(auth_type='file'): 15 def deco(func): 16 def wrapper(*args, **kwargs): 17 if auth_type == 'file': 18 if current_user['user']: 19 return func(*args, **kwargs) 20 name = input('name: ').strip() 21 password = input('password: ').strip() 22 23 with open('db.txt', encoding='utf-8') as f: 24 user_dic = eval(f.read()) 25 if name in user_dic and password == user_dic[name]: 26 res = func(*args, **kwargs) 27 current_user['user'] = name 28 return res 29 else: 30 print('user or password error') 31 elif auth_type == 'mysql': 32 print('mysql') 33 34 elif auth_type == 'ldap': 35 print('ldap') 36 else: 37 print('not valid auth_type') 38 return wrapper 39 return deco 40 41 42 43 @timmer #index=timmer(wrapper) 44 @auth() # @deco #index=deco(index) #wrapper 45 def index(): 46 '''这是index函数''' 47 time.sleep(3) 48 print('welcome to index') 49 return 123 50 51 # print(index.__doc__) 52 # print(help(index)) 53 54 index()
志不强者智不达