Python学习笔记(5)

闭包

Python 中一切皆对象

  • 函数也是对象
  • 可以把一个函数当成另外一个参数,传递到另外的函数里,也可以把一个函数当做另一个函数的返回值

什么是闭包

  • 闭包:函数 + 上下文(环境变量)
  • 闭包的信息保存在函数的__closure__
1
2
3
4
5
6
7
8
9
10
11
12
13
def curve_pre():
a = 25

# 这个闭包捕获了a
def cureve(x):
return a * x * x
return cureve


a = 4
f = curve_pre()
print(f(2)) # 100
print(f.__closure__[0].cell_contents) # 25

使用闭包注意事项

  • 如果没有捕获变量,则closure为空
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def f1():
a = 10

# 此时f2不是一个闭包,因为没有捕获变量
def f2():
# a 是一个局部变量,不会影响外部的变量
a = 20
print(a)
print(a)
f2()
print(a)
return f2


f = f1() # 10 20 10
print(f.__closure__) # None

闭包的应用

  • 闭包可以封装细节
1
2
3
4
5
6
7
8
9
10
11
12
13
def factory(pos):
def go(step):
nonlocal pos # 声明pos不是局部变量
new_pos = pos + step
pos = new_pos # pos如果不声明为非局部变量则这一句户报错
return new_pos
return go


a = factory(0)
print(a(2)) # 2
print(a(3)) # 5
print(a(5)) # 10

函数式编程

lambda 表达式 (匿名函数)

1
2
3
4
5
6
7
8
9
# 普通函数
def add(x, y):
return x + y
sum = add(1, 2)
print(sum)

# lambda表达式
sum = lambda x, y: x + y
print(sum(1, 2))

三元表达式

  • 条件为真的返回结果 if 条件判断 else 条件为假的返回结果
  • 相当于其他语言的?:表达是
1
2
3
4
5
a = 12
b = 13
# 如果a大于b则r等于a否则r等于b
r = a if a > b else b
print(r)

高阶函数

map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def fun(a):
return a * a
a = [1, 2, 3, 4]
b = map(fun, a)
print(list(b))

c = map(lambda value: value * value, a)
print(list(c))

# map可以传入多个列表
l1 = [1, 2, 3, 4]
l2 = [2, 4, 6, 8]
r = map(lambda x, y: x + y, l1, l2) # 传入列表的个数与lambda表达式参数的个数一样
print(list(r)) # [3, 6, 9, 12]

reduce

1
2
3
4
5
6
from functools import reduce

l1 = [1, 2, 3, 4, 5]

r = reduce(lambda x, y: x + y, l1, 0)
print(r) # 15

filter

1
2
3
4
5
6
from functools import reduce

l1 = [1, 2, 3, 4, 5]

r = filter(lambda x: x % 2 == 0, l1)
print(list(r)) # [2, 4]