一 装饰是什么
装饰器是 闭包函数的一种应用,只不过其传递的是函数。装饰器的返回值也是一个函数对象。
装饰器原则:
装饰器原则:1、不修改被装饰对象的 源代码 2、不修改被装饰对象的 调用方式 达到的目标: 在遵循1和2的前提下,为被装饰对象添加新功能
简而言之:@a 就是将 b 传递给 a(),并返回新的 b = a(b)
import time def timer(func): def internal(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) stop_time = time.time() print('run time is {}'.format(stop_time - start_time)) return res return internal @timer #相当于 test = timer(test) def test(): time.sleep(3) print('Hello World') test() #结果: # Hello World # run time is 3.0008761882781982
二 装饰器的使用:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import time def timer(func): def internal(*args,**kwargs): start_time = time.time() res = func() stop_time = time.time() print('run time is {}'.format(stop_time - start_time)) return res return internal @timer def test(): time.sleep(3) print('from test') test()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def auth2(auth_type): def auth(func): def internal(*args,**kwargs): if auth_type == 'file': name = input('username:') pwd = input('password:') if name == 'tom' and pwd == '123': print('Auth Success') res = func(*args,**kwargs) return res else: print('Auth error') elif auth_type == 'sql': print('sql 先停停') return internal return auth @auth2(auth_type='file') def index(): print('Hello') index()
三 wrapper返回的不是原函数的帮助信息
当我们使用了装饰器的时候,虽然没有修改代码本身,但是在运行的时候,比如上面这个例子,运行index其实在运行internal了,如果我们打印my_index的注释信息,会打印internal的注释信息,那么该如何处理?
import time def timer(func): def internal(): """计算运行时间""" stat_time = time.time() res = func() stop_time = time.time() print('run time is {}'.format(stop_time - stat_time)) return res return internal @timer def index(): """世界 你好""" #原始注释信息 print('Hello World') index() print(index.__doc__) #结果: Hello World run time is 0.0 计算运行时间 #并不是想要的
解决方法:
import time from functools import wraps def timer(func): @wraps(func) def internal(): """计算运行时间""" stat_time = time.time() res = func() stop_time = time.time() print('run time is {}'.format(stop_time - stat_time)) return res return internal @timer def index(): """世界 你好""" print('Hello World') time.sleep(1) index() print(index.__doc__) #结果: Hello World run time is 1.0004730224609375 世界 你好