03-闭包
1.什么是闭包?
闭包(Closure)是指一个函数在其定义的环境之外被调用时,仍然能够访问其定义时的作用域中的变量。
简单来说,闭包就是 “函数+定义时的环境变量”的组合。
闭包的基本构成:
- 嵌套函数(函数内部定义函数)。
- 内部函数引用了外部函数的变量。
- 外部函数返回内部函数。
2.闭包的核心和关键
- 环境变量的引用:
闭包的核心在于内部函数可以“记住”并访问外部函数作用域中的变量,即使外部函数已经执行完毕。
- 作用域和生命周期:
通常,函数执行结束后其局部变量会被销毁。但闭包中的变量会因为被内部函数引用而不会被立即销毁,从而延长了这些变量的生命周期。
- nonlocal关键字(可选):
如果需要在闭包中修改外部函数的变量,可以使用 nonlocal
关键字。
3.闭包的示例
def outer_function(x):
def inner_function(y):
return x + y # 内部函数引用了外部函数的变量 x
return inner_function # 外层函数的返回值必须是内层函数的函数名
# 创建闭包
closure = outer_function(10)
# 调用闭包
result = closure(5) # 相当于执行 10 + 5
print(result) # 输出 15
解释:
outer_function(10)
返回inner_function
,并且x=10
被保存在闭包中。closure(5)
调用inner_function
,此时x=10
和y=5
,最终返回15
。
4.闭包的应用场景
- 延迟计算(惰性求值):
将参数和环境保存在闭包中,等到需要时再进行计算。
- 数据封装与隐藏:
闭包可以用来创建类似私有变量的效果,防止外部直接访问或修改数据。
- 回调函数和装饰器:
闭包是实现装饰器的基础,允许在不修改函数源代码的情况下扩展功能。
5.闭包的实际应用示例
- 数据封装:
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter # 这里不是返回 counter 的调用,是返回其引用
# 创建一个计数器闭包
counter1 = make_counter()
print(counter1()) # 输出 1
print(counter1()) # 输出 2
counter2 = make_counter()
print(counter2()) # 输出 1(新的计数器独立)
- 实现简单的装饰器:
def simple_decorator(func):
def wrapper():
print("Before calling the function")
func()
print("After calling the function")
return wrapper
@simple_decorator
def say_hello():
print("Hello!")
say_hello()
输出:
Before calling the function
Hello!
After calling the function
总结
闭包的核心在于 函数对外部作用域变量的引用,即使外部函数已经返回,闭包依然能够访问这些变量。闭包常用于数据封装、延迟计算、装饰器等场景,提供了更强大的功能和灵活性。
闭包
和 嵌套函数
的关键区别:
闭包:一定是在外层函数中返回内层函数的名称(引用);而嵌套函数则没有这一硬性要求:
# 闭包结构如下:伪代码
def outer():
def inner():
return 2 # 内层函数可以没有返回值
return inner # 闭包硬性要求:必须在外层函数中返回内层函数的名称
# 嵌套函数结构如下:伪代码
def outer():
def inner():
return 2
inner() # 嵌套函数这里没有 return,而是直接调用了 内层函数