装饰器decorator
装饰器本质
装饰器的本质是一个函数
装饰器的实现:将函数作为参数传给装饰器,装饰器返回一个在原有基础上添加额外功能的新函数
装饰器示例-统计函数运行时间
原始方式使用装饰器:
import time
# 计算1-n之间每个数的平方相加
def calc_func(n):
sum = 0
for i in range(1, n + 1):
sum += i ** 2
return sum
# 定义装饰器,功能:计算函数运行时间
def elapsed_time(func):
def inner(*args, **kwargs):
start = time.time()
r = func(*args, **kwargs)
end = time.time()
print(f"运行时间:{end - start}")
return r
return inner
if __name__ == '__main__':
# 使用装饰器-方式一
calc_func = elapsed_time(calc_func)
res = calc_func(10000000)
print(res)
"""
输出:
运行时间:2.243622064590454
333333383333335000000
"""
语法糖@使用装饰器
import time
# 定义装饰器,功能:计算函数运行时间
def elapsed_time(func):
def inner(*args, **kwargs):
start = time.time()
r = func(*args, **kwargs)
end = time.time()
print(f"运行时间:{end - start}")
return r
return inner
# 计算1-n之间每个数的平方相加
# 使用装饰器-方式二
@elapsed_time
def calc_func(n):
sum = 0
for i in range(1, n + 1):
sum += i ** 2
return sum
if __name__ == '__main__':
print(calc_func(10000000))
"""
输出:
运行时间:2.3276569843292236
333333383333335000000
"""
小结
两种使用装饰器方法是等价的,@...是python的语法糖。
语法糖:指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。
进阶-给装饰器中传参
想实现如@elapsed_precision(3)可以传参,请看如下代码
import time
# 定义装饰器
def elapsed_precision(precision):
def elapsed_time(func):
def inner(*args, **kwargs):
start = time.time()
r = func(*args, **kwargs)
end = time.time()
print(f"运行时间:{round(end - start, precision)}")
return r
return inner
return elapsed_time
# 计算1-n之间每个数的平方相加
# 使用装饰器
@elapsed_precision(3)
def calc_func(n):
sum = 0
for i in range(1, n + 1):
sum += i ** 2
return sum
if __name__ == '__main__':
print(calc_func(10000000))
"""
输出:
运行时间:2.221
333333383333335000000
"""
总
所以想要理解装饰器,首先要明白在python中一切皆对象,函数是可以作为参数/变量传递的。装饰器本质上是一个函数,要装饰的函数作为参数传给装饰器,经装饰返回一个新函数
视频:https://www.bilibili.com/video/BV1e84y1D7TU?vd_source=aabfec6889cec4fa4fe8e19267634a32