1、定义:
(1)装饰器指的是为被装饰对象添加额外功能的工具/函数。
2、使用装饰器的意义(原因):
如果我们已经上线了一个项目,我们需要修改某一个方法,但是我们不想修改方法的使用方法,这个时 候可以使用装饰器。因为软件的维护应该遵循开放封闭原则,即软件一旦上线运行后,软件的维护对修改源代码是封闭的,对扩展功能指的是开放的。
3、装饰器的实现必须遵循两大原则:
- 封闭: 对已经实现的功能代码块封闭。 不修改被装饰对象的源代码
- 开放: 对扩展开发 装饰器其实就是在遵循以上两个原则的前提下为被装饰对象添加新功能。
4、如何实现装饰器?
装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。
*******饰器的通用模板*******(很重要)
from functools import wrapsdef function(func): #func===被装饰的函数@wraps(func) #保留被装饰函数的名字和帮助文档def wrapper(*args, **kwargs): #形参,可变参数(元组),关键字参数(字典)"""被装饰函数前需要添加的内容"""result = func(*args, **kwargs) # 实参,解包"""被装饰函数后需要添加的内容"""return resultreturn wrapper
5、装饰器的应用场景:
装饰器经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、 权限校验等应用场景。
装饰器典型应用场景:
Django框架装饰器应用:http://y.tsutsumi.io/dry-principles-through-python-decorators.html
(1)插入日志
from functools import wraps# 定义装饰器
def logger(func):"""插入日志的装饰器"""@wraps(func)def wrapper(*args, **kwargs):print("函数%s开始执行" % (func.__name__))result = func(*args, **kwargs)print("函数%s执行结束" % (func.__name__))return resultreturn wrapper# 使用装饰器
@logger # 语法糖 执行: login = logger(login) 将login通过logger函数进行装饰,返回wrapper
def login(username, password):if username == 'root' and password == '123':print('login ok')print('%s login ok' % (username))else:print('login failed')print('%s login failed' % (username))if __name__ == '__main__':login('root', '123') # 实质执行的是wrapper函数
# ---- 运行结果-----
# 函数login开始执行
# login ok
# root login ok
# 函数login执行结束
(2)性能测试
比如:计算代码运行时间
from functools import wraps
import timedef timeit(func): # 2 func=download_music"""打印被装饰函数运行总时间的装饰器"""# @wraps保留被装饰函数的函数名和帮助文档, 否则是wrapper的信息.@wraps(func)def wrapper(*args, **kwargs): # 5 args=('Music', ), kwargs={}start_time = time.time()result = func(*args, **kwargs) # 6 func('Music')=download_music('Music')end_time = time.time()print("%s函数运行总时间为%fs" %(func.__name__, end_time-start_time))return result # 7return wrapper # 3@timeit # 1 @timeit实质上执行的内容: download_music = timeit(download_music) = wrapper
def download_music(name): # 7time.sleep(0.4)print('[Download]: ', name)return True# 调用download_music函数时实质上调用的是wrapper函数。
download_music('Music') # 4
运行结果:
[Download]: Music
download_music函数运行总时间为0.420078s
参考自https://blog.csdn.net/daidadeguaiguai/article/details/103672492