装饰器需要掌握以下知识点:
1.为被装饰对象提供新功能的工具
2.装饰器本身、被装饰对象可以是任意可调用对象
3.软件一旦上线后,应该对修改封闭,对扩展开放
4.原则:
- 不修改被装饰对象的源代码
- 不修改被装饰对象的调用方式
5.示例代码1无参装饰器:用装饰器(outter)实现统计一个函数(inner)的执行时间
#示例代码1 import time # 装饰器 def outter(func): def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print('run time is %s' % (end_time - start_time)) return res return wrapper # 被装饰函数 @outter # inner = outter(inner) def inner(): print("This is inner.") time.sleep(3) @outter # home = outter(home) def home(name): print('welcome %s' %name) time.sleep(2) return 123 inner() print('-----') home('cooky')
6.示例代码2:装饰器模板
#示例代码2 def outter(func): def inner(*args, **kwargs): res = func(*args, **kwargs) return res return inner
7.示例代码3无参装饰器:模拟实现用户验证
#示例代码3 import time current_userinfo = {'user':None} def outter(func): def wrapper(*args, **kwargs): if current_userinfo['user']: return func(*args, **kwargs) user = input('please input your username:').strip() pwd = input('please input your password:').strip() if (user == 'cooky' and pwd == '123'): print('login successfully') current_userinfo['user'] = user res = func(*args, **kwargs) return res else: print('login failed') return wrapper @outter def inner(): print("This is inner.") time.sleep(3) @outter def home(name): print('welcome %s' %name) time.sleep(2) return inner() home('cooky')
8.示例代码4:多个装饰器的执行顺序:语法自下而上解析,执行过程为从上到下。记住结论为自上而下执行代码就可以了
@outter1
@outter2
def index():
print('this is index')
#示例代码4 def outter1(func): print('2.this is outter1') def wrapper1(*args, **kwargs): print('3.this is wrapper1') res = func(*args, **kwargs) return res return wrapper1 def outter2(func): print('1.this is outter2') def wrapper2(*args, **kwargs): print('4.this is wrapper2') res = func(*args, **kwargs) return res return wrapper2 @outter1 @outter2 def index(): print('5.this is index') index()
9.示例代码5:有参装饰器
#示例代码5 import time current_userinfo={'user':None} def auth(engine = 'file'): def outter(func): def wrapper2(*args, **kwargs): if engine == 'file': if current_userinfo['user']: return func(*args, **kwargs) user = input('please input your username:').strip() pwd = input('please input your password:').strip() if (user == 'cooky' and pwd == '123'): print('login successfully') current_userinfo['user'] = user res = func(*args, **kwargs) return res else: print('login failed') elif engine == 'mysql': print('mysql认证机制') elif engine == 'ldap': print('ldap的认证机制') else: print('不支持改engine') return wrapper2 return outter @auth(engine = 'ldap') def index(): print('welcome to index page') time.sleep(3) index()
10.示例代码6:wraps装饰器实现原始函数的文档和装饰后函数的文档一致
#示例代码6 from functools import wraps def outter(func): @wraps(func) def wrapper(*args, **kwargs): res = func(*args, **kwargs) return res return wrapper @outter def inner(): """ this is inner's document :return: """ print('this is inner') print(help(inner)) print(inner.__name__)
扫描二维码关注公众号,回复:
2351557 查看本文章
![](/qrcode.jpg)