Flask 中的装饰器
看到这里你可能会问:咱们这门课程不是学习 Flask 框架吗?怎么又扯到装饰器上面去了?
这是因为装饰器语法在 Flask 框架中得到了广泛的应用,想要学好 Flask 框架不理解装饰器的概念是不行滴。
因此这个小节我们就专门来讨论下装饰器的用途、定义和原理,为大家深入理解 Flask 框架原理打下一个重要基础。
1. 高阶函数
1.1 把函数当作对象
本节从底层原理讲解了如何实现装饰器,学员需要深入理解 Python 中 “函数是第一类对象” 的概念,可以参考词条 “Python 的 lambda 表达式”。在这个词条中对这一概念具有比较系统的讲解。
- 被赋值给变量;
- 作为参数传递给函数;
- 作为返回值。
- 被赋值给变量;
- 作为参数传递给函数;
- 作为返回值。
1.2 把函数作为输入参数
def double(item):
return item + item
def triple(item):
return item + item + item
def map(func, input):
output = []
for item in input:
new_item = func(item)
output.append(new_item)
return output
print(map(double, [, , ]))
print(map(triple, [, , ]))
运行程序,输出如下:
[2, 4, 6]
[3, 6, 9]
序列 [1, 2, 3] 中的每个元素乘以 2 后,得到序列 [2, 4, 6];序列 [1, 2, 3] 中的每个元素乘以 3 后,得到序列 [3, 6, 9]。
1.3 把函数作为返回值
在下面的例子中,将函数作为返回值:
def func():
print('Inside func')
def return_func():
print('Inside return_func')
return func
var = return_func()
var()
程序的输出结果如下:
Inside return_func
Inside func
2. 装饰器与高阶函数
通过上面的两个例子我们可以了解到高阶函数有两个特性:
函数 decorate 对函数 input 的功能进行扩充,生成并返回一个新的函数 output,新的函数 output 的功能基于函数 input。装饰器的中装饰的含义是指:对函数 input 的功能进行装饰 (扩充功能),得到一个新函数 output。
3. 装饰器的用途
3.1 需求
使用 Python 编写了 3 种排序算法:
- quick_sort,快速排序;
- bubble_sort,冒泡排序;
- select_sort,选择排序。
现在需要对这 3 个算法进行性能评测,记录并打印每个排序算法的执行时间。
import time
def quick_sort():
time.sleep()
def bubble_sort():
time.sleep()
def select_sort():
time.sleep()
引入 time 模块,使用 time.sleep () 模拟函数的执行时间;使用 time.sleep (1) 模拟 quick_sort 的执行时间为 1 秒;使用 time.sleep (2) 模拟 bubble_sort 的执行时间为 2 秒;使用 time.sleep (3) 模拟 select_sort 的执行时间为 3 秒。
3.2 不使用装饰器
对于这个需求,我们先不使用装饰器,仅使用 Python 的基础语法完成任务,如下所示:
import time
def quick_sort():
start_time = time.time()
time.sleep()
end_time = time.time()
print('%.2f seconds' % (end_time - start_time))
def bubble_sort():
start_time = time.time()
time.sleep()
end_time = time.time()
print('%.2f seconds' % (end_time - start_time))
def select_sort():
start_time = time.time()
time.sleep()
end_time = time.time()
print('%.2f seconds' % (end_time - start_time))
quick_sort()
bubble_sort()
select_sort()
1.00 seconds
2.00 seconds
3.00 seconds
3.3 使用装饰器
import time
def quick_sort():
time.sleep()
def bubble_sort():
time.sleep()
def select_sort():
time.sleep()
在上一节的例子中,需要对 quick_sort、bubble_sort 和 select_sort 进行修改。在本节的例子中,不对 quick_sort、bubble_sort 和 select_sort 进行任何修改。
def decorate(input_sort):
def output_sort():
start_time = time.time()
input_sort()
end_time = time.time()
print('%.2f seconds' % (end_time - start_time))
return output_sort
quick_sort = decorate(quick_sort)
bubble_sort = decorate(bubble_sort)
select_sort = decorate(select_sort)
使用 decorate (quick_sort),生成一个功能增强的 quick_sort,并替换原有的 quick_sort;使用 decorate (bubble_sort),生成一个功能增强的 bubble_sort,并替换原有的 bubble_sort;使用 decorate (select_sort),生成一个功能增强的 select_sort,并替换原有的 select_sort。
quick_sort()
bubble_sort()
select_sort()
1.00 seconds
2.00 seconds
3.00 seconds
4. Python 的装饰器语法
4.1 装饰器语法
def decorate(input_function):
def output_function():
pass
return output_function
@decorate
def input_function():
pass
def decorate(input_function):
def output_function():
pass
return output_function
def input_function():
pass
input_function = decorate(input_function)
decorate 函数接受输入参数 input_function,返回一个功能增强的函数 output_function。 用功能增强的新函数 output_function 替换原有的旧函数 input_function。
4.2 使用装饰器语法
在本小节,使用 Python 的装饰器语法实现对三种排序算法的性能评测:
import time
def decorate(input_sort):
def output_sort():
start_time = time.time()
input_sort()
end_time = time.time()
print('%.2f seconds' % (end_time - start_time))
return output_sort
@decorate
def quick_sort():
time.sleep()
@decorate
def bubble_sort():
time.sleep()
@decorate
def select_sort():
time.sleep()
使用装饰器 decorate 装饰 quick_sort,得到一个功能增强的 quick_sort;使用装饰器 decorate 装饰 bubble_sort,得到一个功能增强的 bubble_sort;使用装饰器 decorate 装饰 select_sort,得到一个功能增强的 select_sort。
quick_sort()
bubble_sort()
select_sort()
1.00 seconds
2.00 seconds
3.00 seconds