先看下下面的闭包函数热下身
def outer(x):
def inner(y):
nonlocal x # 使用 nonlocal,使内部函数可以修改外部函数的变量。
x = x + y
return x + y
return inner
fun = outer(10)
print(fun(10)) # 第一个 fun(10)
print(fun(10)) # 第二个 fun(10)
print(fun(10)) # 第三个 fun(10)
其运行结果为:
30
40
50
三个 fun(10) 的运行结果是不同的,分别为30,40,50。
为什么会这样呢?
这就是闭包的效果,它可以保持局部变量不被系统回收。
首先看第一个 fun(10) , 其相当于fun(10) = outer(10)(10) 。
def outer(10): # 传入的 x = 10
def inner(10): # 传入的 y = 10
nonlocal x # 使用 nonlocal
x = 10 + 10 # >>> 此时 x = 20 了
return x + y # 最后 return 20 + 10 = 30
return inner
第一个 print(fun(10)) 运行结束后,变量 x = 20,且“储存”在 fun = outer(10) 中。
然后是第二个 print(fun(10)):
def outer(x):
def inner(10): # 传入的y = 10
nonlocal x # 使用 nonlocal, 此时的 x 已是 20 了。
x = 20 + 10 # >>> 此时 x = 30 了
return x + y # 最后 return 30 + 10 = 40
return inner
同理,所以最后 第二个 print(fun(10)) 的输出结果就是 50 了。
闭包的这个功能可以实现既不通过更改全局变量的情况下,进行函数内部变量的传递。
x = 0
def global_test():
x = 10
print(f'1外部函数中的x为:{x}')
def inner():
x = 100
print(f'内部函数的x为:{x}')
inner()
print(f'2外部函数中的x为:{x}')
global_test()
print(f'全局变量x:{x}')
运行结果为:
1外部函数中的x为:10
内部函数的x为:100
2外部函数中的x为:10
全局变量x:0
说明:全局变量和局部变量互不影响,各自独立。
x = 0
def global_test():
global x
x = 10
print(f'1外部函数中的x为:{x}')
def inner():
x = 100
print(f'内部函数的x为:{x}')
inner()
print(f'2外部函数中的x为:{x}')
global_test()
print(f'全局变量x:{x}')
运行结果为:
1外部函数中的x为:10
内部函数的x为:100
2外部函数中的x为:10
全局变量x:10
改变了全局变量,但内部函数中的变量对外部函数和全局变量都没影响。
说明:外部函数的 global 只影响全局变量,而对闭包中内部函数的变量没影响。
x = 0
def global_test():
x = 10
print(f'1外部函数中的x为:{x}')
def inner():
global x
x = 100
print(f'内部函数的x为:{x}')
inner()
print(f'2外部函数中的x为:{x}')
global_test()
print(f'全局变量x:{x}')
运行结果为:
1外部函数中的x为:10
内部函数的x为:100
2外部函数中的x为:10
全局变量x:100
闭包中内部函数的变量对外部函数没影响,但改变了全局变量。
x = 0
def global_test():
global x
x = 10
print(f'1外部函数中的x为:{x}')
def inner():
global x
x = 100
print(f'内部函数的x为:{x}')
inner()
print(f'2外部函数中的x为:{x}')
global_test()
print(f'全局变量x:{x}')
运行结果:
1外部函数中的x为:10
内部函数的x为:100
2外部函数中的x为:100
全局变量x:100
此时内部函数,外部函数,全局变量都已互相关联。只要有一个变动,都会互相影响了。
说明:对于 global 的使用位置,只影响其同层级函数的局部变量与全局变量之间的关联性。
待补充……