学习 python 4 - python 函数式编程「半原创」


本文会带来什么

  1. 高阶函数
  2. 返回函数
  3. 匿名函数
  4. 装饰器
  5. 偏函数

什么是函数式编程?

函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。

1.高阶函数

1
2
3
4
5
6
7
8
9
10
#  --------------高阶函数
# 既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
# 变量指向函数
f = abs
print(f(-1))
# 可以把函数名看做变量
# 传入函数
def aaa(x, y, f):
return f(x) + f(y)
print(aaa(-1, -2,f))

2.map()

mapReduce 是一个比较大的话题,据说是google 三宝之一,感兴趣同学可以 自行 搜索

1
2
3
4
5
6
7
8
#  --------------map()
# map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回
def f(x):
return x * x
r = map(f,[1,2,3])
print(list(r))

# 结果: [1, 4, 9]

3.reduce()

reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

1
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

1
2
3
4
5
6
7
8
9
10
#  --------------reduce()
# 第一个参数函数必为两个参数
from functools import reduce
L = [1,2,3]
def testReduce(x,y):
return x * y
r = reduce(testReduce,L)
print(r)

# 结果: 6

4.filter()

1
2
3
4
5
6
7
8
#  --------------filter()
# 和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素
def fil(x):
return x > 0
L = [-1,-2,0,1,2]
print(list(filter(fil,L)))

# 结果: [1, 2]

5.sorted()

排序算法

1
2
3
4
5
6
7
8
9
#  --------------sorted()
# 一个参数
L = [-1,-2,0,1,2,-4]
print(sorted(L))
# 结果: [-4, -2, -1, 0, 1, 2]

# 两个参数,用函数先行处理, key =
print(sorted(L,key=abs))
# 结果: [0, -1, 1, -2, 2, -4]

6.返回函数

1
2
3
4
5
6
7
8
9
10
11
12
13
# 闭包
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs

f1 ,f2 ,f3= count()
# 结果:三个都是 9
# 返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
# 返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量。

7.匿名函数

1
2
3
4
5
6
7
8
9
10
#  --------------匿名函数
# 有些时候,不需要显式地定义函数,直接传入匿名函数更方便
# : 前面为函数名和参数
print(list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])))
# 结果:[1, 4, 9, 16, 25, 36, 49, 64, 81]
# 限制:只能有一个表达式,不用写return,返回值就是表达式的结果
print()
# 也可以把匿名函数作为返回值返回
def build(x, y):
return lambda: x * x + y * y

8.装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#  --------------装饰器
# 在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)
# 拿到函数的名字
import functools


def now():
print("2015 - 10 -10")
now()
print(now.__name__)
# 在函数调用前后自动打印日志,但又不希望修改now()函数的定义
def log(func):
def wrapper(*args,**kw):
print("item is me ")
return func(*args,**kw)
return wrapper
@log
def now2():
print("2015 - 10 -10")
now2()
# 3次嵌套
def loog(text):
def de(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print("haha:" ,text)
return wrapper
return de

@loog("33333")
def now3():
print("three")

now3()

print(now3.__name__)
# function tool 导入后 属性不变,否则打名字就是 wrapper

9.偏函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#  --------------偏函数
# 可以帮助我们固定参数
# 原始函数:
import functools


def sum(x,y):
return x / y
print(sum(4,5))

# 固定参数
sum2 = functools.partial(sum,y = 2)
print(sum2(4))

# 当为数组时,默认加到左边

L = [1,2,3,6,4]
max2 = functools.partial(max, 10)

print(max2(5, 6, 7))

参考