一、介绍
Python 中的闭包(Closure)是指一个函数对象(称为内部函数)捕获并引用了其所在函数(称为外部函数)中的变量,即使外部函数已经执行完毕,内部函数仍然可以访问和操作外部函数中的变量。闭包在函数式编程中具有重要的作用,可以用于实现许多有用的功能和模式。
要创建一个闭包,需要满足以下条件:
- 必须有一个内部函数。
- 内部函数必须引用外部函数中的变量。
- 外部函数必须返回内部函数。
二、实例
下面是一个简单的闭包示例:
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
closure = outer_function(10)
print(closure(5)) # 输出: 15
在上述示例中,outer_function
是一个外部函数,它接受一个参数 x
。在 outer_function
中定义了一个内部函数 inner_function
,它引用了外部函数中的变量 x
。最后,outer_function
返回了内部函数 inner_function
。
通过调用 outer_function(10)
,我们得到了一个闭包 closure
。闭包 closure
是内部函数 inner_function
的引用,它在捕获了外部函数中的变量 x
的同时保留了该变量的状态。当我们调用 closure(5)
时,实际上是在调用内部函数 inner_function
,它使用了外部函数中的变量 x
,并将参数 y
加到 x
上返回结果。
这里唯一的问题就是,当outer_function(5)
结束之后返回了closure,return
应该是把outer_function函数给关闭了,它的本地作用域也随之消失,为什么
- closure
(5)
还能再次进入outer_function? - 并且还能再次从outer_function的本地作用域调用x+y
三、自由变量的作用域
关于第一个问题,涉及到自由变量作用域的问题下面会阐述,第二个问题,涉及到python的内部机制,这种内嵌函数会将变量存在内存中,并不会直接释放,可以参考闭包原理
全局变量,局部变量的概念大家都清楚,看下面的例子分别定义全局变量,局部变量,这里会打印全局变量a
a = 20 # 全局变量
def inner():
print(a)
def outer():
a = 10 # 局部变量
inner() # 全局变量可以进当前inner函数
outer()
只在函数内部 定义局部变量,inner函数无法找到变量a
def inner():
print(a)
def outer():
a = 2 # 局部变量
inner() # 如果不是内嵌函数,局部变量a的作用域进不了函数inner
outer()
使用内嵌函数,打印变量a
a = 20
def outer():
a = 10
def inner(): #内嵌函数
print(a) #自由变量a的优先级大于全局变量a,打印10
return inner
result = outer() # 闭包
result()
此时变量a是一个自由变量, 自由变量(Free variables)是指在闭包中被内部函数引用但不是内部函数的参数或局部变量的变量。
在闭包中,自由变量的作用域如下:
-
外部函数作用域:自由变量在外部函数中定义,因此在外部函数内部的任何地方都可以访问和使用自由变量。
-
内部函数作用域:内部函数是闭包中实际执行的函数,它可以访问和使用外部函数的自由变量。
其他例子
def outer_function():
x = 10
def inner_function():
print(x) # x的作用域在内部函数与外部函数
inner_function()
outer_function() # 输出 10
四、总结
闭包的一个重要特性是它可以记住外部函数中的状态。每次调用外部函数时,都会创建一个新的闭包,每个闭包都保留了自己的外部函数变量的状态。这使得闭包非常适合用于创建具有持久状态的函数,例如计数器、缓存等。
闭包在实际编程中具有广泛的应用,可以用于实现回调函数、装饰器、延迟计算等功能。通过利用闭包,可以更灵活地组织和管理代码。
参考:
python之闭包详解_闭包python_小蜗牛-笨笨的博客-CSDN博客
python---闭包_python闭包_最初的梦10的博客-CSDN博客