Skip to main content

03-闭包

1.什么是闭包?

闭包(Closure)是指一个函数在其定义的环境之外被调用时,仍然能够访问其定义时的作用域中的变量。

简单来说,闭包就是 “函数+定义时的环境变量”的组合。

闭包的基本构成:

  1. 嵌套函数(函数内部定义函数)。
  2. 内部函数引用了外部函数的变量。
  3. 外部函数返回内部函数。

2.闭包的核心和关键

  1. 环境变量的引用:

闭包的核心在于内部函数可以“记住”并访问外部函数作用域中的变量,即使外部函数已经执行完毕。

  1. 作用域和生命周期:

通常,函数执行结束后其局部变量会被销毁。但闭包中的变量会因为被内部函数引用而不会被立即销毁,从而延长了这些变量的生命周期。

  1. 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=10y=5,最终返回 15

4.闭包的应用场景

  1. 延迟计算(惰性求值):

将参数和环境保存在闭包中,等到需要时再进行计算。

  1. 数据封装与隐藏:

闭包可以用来创建类似私有变量的效果,防止外部直接访问或修改数据。

  1. 回调函数和装饰器:

闭包是实现装饰器的基础,允许在不修改函数源代码的情况下扩展功能。

5.闭包的实际应用示例

  1. 数据封装:
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(新的计数器独立)
  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,而是直接调用了 内层函数