一、闭包的介绍
闭包可以保存函数内的变量
当闭包执行完毕,外部函数的变量才释放。
# 闭包的作用:可以保存外部函数的变量
# 闭包的形成条件
# 1.函数嵌套
# 2.内部函数使用了外部函数的变量或者参数
# 3.外部函数返回内部函数。这个使用了外部函数变量的内部函数称为闭包
# 1.函数嵌套
def func_out(): # 外部函数
num1 = 10
def func_inner(num2): # 内部函数
result = num1 + num2 # 2.内部函数使用外部函数的变量或者参数
print("结果为:{}".format(result))
return func_inner # 3.外部函数返回内部函数,不能写func_inner()
# 获取闭包对象
new_func = func_out() # 这个new_func就是闭包,这里的new_func=func_inner
new_func(1) # 执行闭包
new_func(10)
输出:
结果为:11
结果为:20
二、闭包的使用
# 外部函数接收姓名
def config_name(name):
# 内部函数保存外部函数的参数,并且完成数据显示的组成
def inner(msg):
print(name + "说:" + msg)
# 外部函数返回内部函数
return inner
# 创建闭包实例对象
tom = config_name("tom") # 闭包一旦创建完成,外部函数的变量或参数name就定了,以后就不用再传了
jerry = config_name("jerry")
# 执行闭包
tom("哥们,过来一下,我们一起玩耍")
# 执行tom()的时候就是执行inner,在执行inner的时候传了一个参数"哥们,过来一下,我们一起玩耍"给msg,在inner函数内部组织之前一直保存的name参数
jerry("明天可以吗?")
输出:
tom说:哥们,过来一下,我们一起玩耍
jerry说:明天可以吗?
这里,通过tom = config_name("tom") 和 jerry = config_name("jerry")
,实际上只用了一份代码就创建了两个实例,然后在调用tom()和jerry()的时候,print(name + "说:" + msg)
也只是用了这一份代码,提高了代码复用性。
三、修改闭包内使用的外部变量
简言之,闭包就是那个内部函数,修改闭包内使用的外部变量,就是在内部函数里修改外部变量。
在闭包内修改外部函数的变量,需使用nonlocal关键字。
def func_out():
num1 = 10
def func_inner(): # 1.函数嵌套
num1 = 20 # 在闭包内修改外部函数的变量
result = num1 + 10 # 2.内部函数使用外部函数变量
print(result)
return func_inner # 3.返回内部函数
new_func = func_out() # 创建一个闭包实例
new_func() # 调用闭包实例
输出:30
def func_out():
num1 = 10
def func_inner(): # 1.函数嵌套
num1 = 20 # 在闭包内修改外部函数的变量
result = num1 + 10 # 2.内部函数使用外部函数变量
print(result)
print("修改前的外部变量:", num1)
func_inner()
print("修改后的外部变量:", num1)
return func_inner # 3.返回内部函数
new_func = func_out() # 创建一个闭包实例
输出:
修改前的外部变量: 10
30
修改后的外部变量: 10
可见,在创建闭包的时候程序就已经运行了,并且在内部函数里不能直接修改外部函数的变量值
def func_out():
num1 = 10
def func_inner(): # 1.函数嵌套
global num1
num1 = 20 # 在闭包内修改外部函数的变量
result = num1 + 10 # 2.内部函数使用外部函数变量
print(result)
print("修改前的外部变量:", num1)
func_inner()
print("修改后的外部变量:", num1)
return func_inner # 3.返回内部函数
new_func = func_out() # 创建一个闭包实例
输出:
修改前的外部变量: 10
30
修改后的外部变量: 10