当一个函数接收另一个函数作为参数时,我们将其称为高阶函数。例如之前提到的装饰器,map,filter等。
Python中有一个专门使用高阶函数的模块叫做functools,其中包含了很多实用的高阶函数和装饰器,以下是functools中的几个重点函数:
1.reduce()函数:将可迭代对象中的元素依次传递到第一个参数指定的函数中。
import functools
def add(a,b):
return a+b
print(functools.reduce(add, [1,2,3,4,5,6]))
## 21
# 其本质类似于
# add(add(add(add(add(1,2),3),4),5),6)
因此我们还可以将reduce函数第一个参数写成lambda表达式。
import functools
print(functools.reduce(lambda x,y:x*y , [1,2,3,4,5,6]))
## 720
# 同时,可迭代对象的形式也可以发生改变。
print(functools.reduce(lambda x,y:x*y , range(1,7)))
## 720
2.偏函数:对指定的函数进行二次包装,通常是将现有的函数部分参数预先绑定,从而得到的新的函数。作用是将一个函数的多个参数给拆分,多次进行传递。
import functools
square = functools.partial(pow, exp=2)
print(square(2))
print(square(3))
## 4
## 9
cube = functools.partial(pow, exp=3)
print(cube(2))
print(cube(3))
## 8
## 27
3.@wraps装饰器
对于常见的装饰器,我们通过对其自省,便可以发现
import time
def times(func):
def call_func():
print("开始运行该程序...")
start = time.time()
func()
stop = time.time()
print(f"一共耗费了{(stop - start) * 1000:.2f}ms")
return call_func
@times
def myfun():
time.sleep(2)
print("I Love Cloud")
print(myfun.__name__)
## call_func
对于func函数,我们却得到了call_func这一个名称,为了解决这一问题,我们导入了@wraps装饰器。
import time
import functools
def times(func):
@functools.wraps(func)
def call_func():
print("开始运行该程序...")
start = time.time()
func()
stop = time.time()
print(f"一共耗费了{(stop - start) * 1000:.2f}ms")
return call_func
@times
def myfun():
time.sleep(2)
print("I Love Cloud")
print(myfun.__name__)
## myfun
调用functools库,找到函数闭包中真正调用的函数,在其上方使用wraps,便可以得到想要的结果。