Python 装饰器笔记
装饰器的作用
在不修改原函数的内部代码、不修改原函数的调用方式、不重复调用原函数的条件下,为原函数增加扩展功能。
装饰器结构
def deco_name (func) : #装饰器需要接收一个函数名称变量,返回值是一个函数
def wrapper (*args, **kwargs) : #传给原函数func的参数
<statements>...
res = func(*args, **kwargs) #记录原函数func的返回值
<statements>...
return res
return wrapper #返回一个函数;此处才真正调用wrapper()函数,之前的都是函数声明,没有真正调用!
#语法糖,等同于func=deco_name(func)?
@deco_name
def func (parameters...) : #需要添加扩展功能的原函数
<statements>...
return ...
装饰器必须采用内嵌函数,即必须在装饰器函数内部再定义一个函数,Why?
假如不采用内嵌函数,则deco_name函数的定义如下:
def deco_name (func) :
<statements>...
func()
<statements>...
这样导致必须要用deco_name(func)的形式才能达到装饰器调用的效果,改变了原来的func()调用的形式。
下例是一个装饰器的例子,可以计算出函数运行的时间,分别作用于冒泡排序和选择排序上:
import time
import random
#Decorator
def deco_time(func) :
def wrapper(*args, **kwargs) :
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print('运行时间(sex): %s' %round((end_time - start_time),10))
return res
return wrapper
#Bubble Sort
@deco_time
def Bubble_Sort(ls) :
print("冒泡排序:")
nums = len(ls)-1
for i in range(0, nums) :
for j in range(0, nums-i) :
if(ls[j]>ls[j+1]) :
ls[j], ls[j+1] = ls[j+1], ls[j]
return ls
#Selection Sort
@deco_time
def Selection_Sort(ls) :
print("选择排序:")
nums = len(ls)-1
for i in range(0, nums) :
min_index = i
for j in range(i, nums) :
if(ls[min_index]>ls[j]) :
min_index = j
ls[i], ls[min_index] = ls[min_index], ls[i]
return ls
#生成随机数列
ls1=[]
for i in range(20) : #数列元素的个数
ls1.append(random.randint(0,100))
ls2=ls1.copy()
#排序
print ("原始数列:\t",ls1)
print()
print ("Bubble Sort:\t",Bubble_Sort(ls1))
print()
print ("Selection Sort:\t", Selection_Sort(ls2))