- 什么时候用装饰器
想要给函数动态的增加一些额外的功能。
Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。 - 不加@wraps(func),函数的名字就是wrapper
- 加@wraps(func),可以保留被装饰前的函数名
- 外层函数嵌套内层函数
- 外层函数返回内层函数
- 内层函数要使用外层函数传递的参数
调用函数,如果带括号,那么是调用函数运行后的结果,
调用函数不带括号,调用的是函数本身
"""__author__= 雍新有"""
import random
import time
from functools import wraps
def record_time(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f'{func.__name__}执行时间: {end - start}秒')
return result
return wrapper
@record_time
def download(filename):
print(f'开始下载{filename}')
time.sleep(random.randint(5, 15))
print(f'{filename}下载完成')
@record_time
def upload(filename):
print(f'开始上传{filename}')
time.sleep(random.randint(5, 15))
print(f'{filename}上传完成')
def main():
print(download.__name__)
print(upload.__name__)
download('Python从入门到住院.pdf')
upload('苍老师.avi')
download.__wrapped__('Python从入门到住院.pdf')
upload.__wrapped__('苍老师.avi')
if __name__ == '__main__':
main()
"""
download
upload
开始下载Python从入门到住院.pdf
Python从入门到住院.pdf下载完成
download执行时间: 8.000381231307983秒
开始上传苍老师.avi
苍老师.avi上传完成
upload执行时间: 13.00049352645874秒
开始下载Python从入门到住院.pdf
Python从入门到住院.pdf下载完成
开始上传苍老师.avi
苍老师.avi上传完成
"""
+ 装饰器在Django中就是中间件middleware
# record_time是一个装饰器函数(装饰别的函数或者类的函数)
# 装饰器函数可以用来装饰一个类或函数
# 如果装饰器用来装饰函数那么他的参数就是被装饰的函数(func)
def record_time(func):
# 装饰器中内嵌的wrapper函数是带装饰功能的函数
# 它除了要执行被装饰的函数之外要执行额外的代码
def wrapper(*args, **kwargs):
# 在执行被装饰的函数之前要做什么
result = func(*args, **kwargs)
# 在执行被装饰的函数之后要做什么
return result
return wrapper()
