1. 闭包是什么?
函数嵌套了一个函数,内部函数使用了外部函数的变量或者形参
并且外部函数返回了内部函数,
我们把这个使用外部函数变量的内部函数 称为闭包。
2. 定义闭包
条件:
1、 定义函数嵌套的前提下(函数中又定义一个函数)
2、 内部函数使用了外部函数的变量或形参
3、 外部函数返回了内部函数 注意:返回函数时不能加小括号,否则就为函数调用
1. 闭包打印
# 1. 定义函数嵌套
def fun(name):
def fun_print():
# 2. 内部函数使用了外部函数的变量或参数
print('{}你好啊,这是我第一个闭包'.format(name))
return fun_print # 3. 外部函数返回了内部函数
# 调用fun()这个函数,返回的是fun_print。所以f保存是一个函数 f = fun_print, 而不是返回值。
f = fun('Hello')
print(f) # <function fun.<locals>.fun_print at 0x0000024FF1B76A60>
f()
打印结果:
<function fun.<locals>.fun_print at 0x00000213F2E669D0>
Hello你好啊,这是我第一个闭包
2. 两个数相加
# 构成闭包
def func_out():
num1 = 1
def func_inner(num2):
res = num1 + num2
print(res)
return func_inner
result = func_out()
result(1) # 这里的实参1 给的是形参num2
打印结果:2
# 构成闭包
def func_out(num1):
def func_inner(num2):
res = num1 + num2
return res
return func_inner
result = func_out(5) # 这里的实参1 给的是形参num1
r = result(1) # 这里的实参1 给的是形参num2
print(r)
打印结果:6
3. 小总结
闭包的作用: 可以保存外部函数内的变量
优点:永久存储局部变量 缺点:占用内存
一般在调用函数时,它的参数和局部变量, 会在函数执行完之后释放
但闭包函数不会,目的是方便在调用内部函数时使用
3. 使用闭包修改外部函数的变量
def fun_outer():
num1 = 10
def fun_inner():
# 在闭包内修改外部函数的变量需要使用nonlocal
nonlocal num1
num1 = 20
result = num1
print(result)
print('num1修改前:', num1)
fun_inner()
print('num1修改后:', num1)
return fun_inner
f = fun_outer()
f()
打印结果:
num1修改前: 10
20
num1修改后: 20
20
4. 小练习
1. 利用闭包聊天
# 1. 构成闭包
def fun_outer(name):
def fun_inner(msg):
print(name + ":" + msg)
return fun_inner
# 2. 使用闭包
bai = fun_outer('小白')
Hong = fun_outer('小红')
bai('你叫什么名字?')
Hong('我叫小红')
Hong('那你呢?')
bai('我是小白')
打印结果:
小白:你叫什么名字?
小红:我叫小红
小红:那你呢?
小白:我是小白
2. 计数器
# 1. 构成闭包
def fun_outer(num1=0):
def fun_inner():
nonlocal num1
num1 += 1
return num1
return fun_inner
# 2. 创建第1个闭包
a = fun_outer()
print(a())
print(a())
print('*'*30)
# 3. 创建第二个闭包
b = fun_outer(6)
print(b())
print(b())
print('*'*30)
# 4. 我重新调用a和b, 结果会变吗?
print(a())
print(b())
打印结果:
1
2
******************************
7
8
******************************
3
9