Python - 闭包:初学者指南

你好,有抱负的Python程序员!今天,我们将开始一段激动人心的旅程,进入闭包的世界。如果你之前从未听说过这个术语,请不要担心——在本教程结束时,你不仅会理解闭包是什么,而且还能在自己的代码中创建和使用它们。那么,让我们开始吧!

Python - Closures

什么是闭包?

想象你有一个神奇的盒子,即使在关闭它之后,它也能记住事情。在编程中,闭包本质上就是这样一种神奇的盒子!在Python中,闭包是一个函数对象,它能够记住封闭作用域中的值,即使它们不在内存中。

听起来很困惑?让我们来分解一下:

  1. 它是另一个函数内部的函数。
  2. 它可以访问外部函数的变量。
  3. 即使外部函数执行完成,它也会记住这些变量。

把它想象成一种创建功能小包的方式,这个小包装载着它自己的私有数据。很酷,对吧?

嵌套函数

在我们深入探讨闭包之前,先来谈谈嵌套函数。这些只是定义在其他函数内部的函数。这里有一个简单的例子:

def outer_function(x):
def inner_function(y):
return x + y
return inner_function

result = outer_function(10)
print(result(5))  # 输出:15

在这个例子中,inner_function嵌套在outer_function内部。内部函数可以访问外部函数的x参数。这是理解闭包的一个关键概念。

变量作用域

要真正掌握闭包,我们需要理解Python中的变量作用域。有三种作用域:

  1. 局部作用域:在函数内部定义的变量
  2. 封闭作用域:嵌套函数外部函数中的变量
  3. 全局作用域:在模块顶层定义的变量

以下是一个示例来说明:

x = "我是全局的!"  # 全局作用域

def outer():
y = "我来自外部!"  # 封闭作用域
def inner():
z = "我是本地的!"  # 局部作用域
print(x, y, z)
inner()

outer()

当你运行这段代码时,你会看到打印出所有三个变量。inner函数可以访问这三个作用域中的所有变量!

创建闭包

现在我们理解了嵌套函数和变量作用域,让我们来创建一个闭包。当嵌套函数引用其封闭作用域中的值时,就会发生闭包。以下是一个例子:

def multiply_by(n):
def multiplier(x):
return x * n
return multiplier

times_two = multiply_by(2)
times_three = multiply_by(3)

print(times_two(5))   # 输出:10
print(times_three(5)) # 输出:15

在这个例子中,multiply_by是我们的外部函数,multiplier是我们的内部函数。当返回multiplier时,魔法就发生了——即使multiply_by执行完成,它也会记住n的值。这就是一个闭包!

让我们逐步分解:

  1. 我们定义了multiply_by,它接受一个参数n
  2. multiply_by内部,我们定义了multiplier,它接受一个参数x
  3. multiplier使用它自己的参数x和外部函数的n
  4. 我们从multiply_by返回multiplier
  5. 当我们调用multiply_by(2)时,它返回一个总是将其输入乘以2的函数。
  6. 同样,multiply_by(3)返回一个总是将其输入乘以3的函数。

这就是闭包的力量——它们可以即时创建专业的函数!

nonlocal关键字

有时,你可能会想在内部函数中修改封闭作用域的变量。Python提供了nonlocal关键字来实现这一点。以下是一个例子:

def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment

my_counter = counter()
print(my_counter())  # 输出:1
print(my_counter())  # 输出:2
print(my_counter())  # 输出:3

在这个例子中,increment是一个闭包,它记住并修改封闭作用域中的count变量。nonlocal关键字告诉Python,count不是局部变量,而是封闭作用域中的变量。

闭包的实际用途

闭包不仅仅是炫酷的技巧——它们有实际的应用!以下是一些例子:

  1. 数据隐藏和封装
  2. 创建函数工厂
  3. 实现装饰器

让我们看一个现实世界的例子。想象你正在为一家在线商店创建一个折扣系统:

def create_price_adjuster(discount):
def adjust_price(price):
return price * (1 - discount)
return adjust_price

black_friday_sale = create_price_adjuster(0.2)  # 20%折扣
cyber_monday_sale = create_price_adjuster(0.15)  # 15%折扣

original_price = 100
print(f"黑色星期五价格:${black_friday_sale(original_price)}")
print(f"网络星期一价格:${cyber_monday_sale(original_price)}")

这段代码为不同的销售活动创建了不同的定价函数,所有这些都使用了相同的基函数。这就是闭包的力量!

总结

恭喜!你刚刚了解了Python的一个更高级的特性。让我们回顾一下我们所学的内容:

概念 描述
闭包 记住封闭作用域中的值的函数
嵌套函数 定义在另一个函数内部的函数
变量作用域 变量的可见性(局部,封闭,全局)
nonlocal 修改封闭作用域中的变量的关键字

请记住,像任何强大的工具一样,闭包应该谨慎使用。它们在执行某些任务时很棒,但过度使用它们可能会使代码更难理解。练习,实验,很快你就能像Python高手一样挥舞闭包了!

编码愉快,请记住——在Python中,就像在生活中一样,内在(函数)才是最重要的!

Credits: Image by storyset