函数式编程
特点:把函数作为参数传入另一个函数,还允许返回一个函数。是一种抽象程度很高的,离底层很远的编程方式,Python也支持变量, 因此并不是存粹的函数式编程语言。
高阶函数
函数,是一段固定的语句。函数名是指向这段语句的变量,因此,函数名可以赋给另一个变量,也可以指向其他变量。
高阶函数,即将函数作为变量传给函数。
例如,将绝对值函数,传入求和函数:
def add(x, y, abs):
return abs(x) + abs(y)
y = add(-3, -4, abs)
print(y)
运行结果:
7
map/reduce
map
map函数包括两个参数,参数一是函数,参数二是一个Iterable, map会对Iterable的每一个元素都执行一个函数,并将生成的结果作为一个新的Iterator返回。
例如:
>>> list(map(abs,[-1,-2,-3,-4,-5]))
[1, 2, 3, 4, 5]
Iterable是惰性的,需要用list函数计算出所有的序列
reduce
reduce接受一个二元函数和一个序列。并将计算结果与序列中的下一个值进行计算。
reduce(f,[x1,x2,x3,x4,x5])=f(f(f(f(x1,x2),x3),x4),x5)
例如:
from functools import reduce
def add(a, b):
return a + b
y = reduce(add, [1, 2, 3, 4, 5])
print(y)
运行结果:
15
filter
作用:对序列满足某些条件的值进行过滤。
使用方法:filter(f,[x1,x2,x3,x4,x5])
其中,f是一个返回值为布尔值的一元函数。filter会留下序列中使f返回值为True的元素。
例如:
def is_odd(a):
return a % 2 == 0
result = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(list(result))
运行结果:
[2, 4, 6, 8]
sorted
作用:进行自定义排序
用法:sorted([x1,x2,x3,x4,x5])
默认进行升序排列
sorted([x1,x2,x3,x4,x5], key=f)
先将每一个元素都用f进行处理再进行升序排列,但是输出的结果还是原来的序列元素
sorted([x1,x2,x3,x4,x5], key=f,reverse=True)
先将每一个元素都用f进行处理再进行降序排列
例如:
>>> sorted(L)
[-5, -4, -3, -2, -1]
>>> sorted(L, key=abs)
[-1, -2, -3, -4, -5]
>>> sorted(L, key=abs, reverse=True)
[-5, -4, -3, -2, -1]
返回函数
本质上是让函数延迟执行。
def f1(x):
def f2():
return result
return f2
>>>f=f1(x)
>>>f
这种情况下,执行f1(x),只不过是进行了一个函数的装载,将f2的代码调入内存,但是并没有分配处理器将其执行。返回值是个函数型变量。
在执行返回的函数型变量时,才是真正执行了这个函数。
注:在将函数装入内存时,因为还没有产生结果,因此,f1内层被f2调用的局部变量如果发生了改变,则会使最终结果差生错误
匿名函数
相当于一种快速定义简单函数的方式
>>> list(map(lambda x: x * x, [1,2,3,4,5]))
[1, 4, 9, 16, 25]
当然,也可以是两个参数:
>>> list(map(lambda L :L[0]+L[1], [[1,2]] ))
[3]
装饰器
作用:可以增强函数的功能,在不修改函数定义的情况下,增加新的功能。
实质:装饰器也是一个函数,它可以接受需要增强功能的函数为变量,在附加功能之后,重新执行该函数。
def log(func): # 以函数作为参数
def wrapper(*args, **kw): #接受原函数的变量,进行附加新的功能
print("call %s()" % func.__name__)
return func(*args, **kw) #执行完新功能后,重新执行原来的函数
return wrapper
@log
def now2():
print('2021-9-3')
now2()
print(now2.__name__)
运行结果:
call now2()
2021-9-3
wrapper
利用Python的@语法完成装饰器。@log放在定义处,相当于执行了now=log(now),将原来的函数变量赋给了wapper函数。
注意,此时now2的名字变成了wrapper,这样不好,因此需要加一个python默认的方法,把比如__name__之类的属性名都赋给新的now2,这样才算是完整的decorator。
import functools
def log(func): # 以函数作为参数
@functools.wraps(func)
def wrapper(*args, **kw): #接受原函数的变量,进行附加新的功能
print("call %s()" % func.__name__)
return func(*args, **kw) #执行完新功能后,重新执行原来的函数
return wrapper
@log
def now2():
print('2021-9-3')
now2()
print(now2.__name__)
偏函数
也是functools模块里的东西。作用是可以固定住参数较多的函数的某些参数,返回一个新的函数。
例如:
import functools
int2 = functools.partial(int, base=2)#相当于把base=2作为一个关键字参数固定在int中
print(int2('10010'))