目录
一、什么是闭包?
闭包是函数式编程的一种重要概念,在Python中也得到了支持。一个闭包就是一个函数对象,不仅能够记住自己在哪个作用域被创建,还能够访问这个作用域内的变量,即使这个作用域已经不存在了。简单来说,就是,当某个函数被当成对象返回时,夹带了外部变量,就形成了一个闭包。
二、闭包的工作原理
1. 作用域
Python有三种作用域:全局作用域、局部作用域和嵌套作用域。当一个函数被定义在另一个函数内部时,内部函数可以访问外部函数的变量。这种机制是闭包的基础。
2. 函数对象和引用环境
闭包涉及到两个主要概念:函数对象和引用环境。
- 函数对象:在Python中,函数是一等公民,意味着它们可以被当作对象来处理,赋值给变量、作为参数传递等。
- 引用环境:函数对象如果引用了它之外的变量,那么这些变量的集合就构成了该函数的引用环境。
3. 创建闭包的条件
要创建一个闭包,需要满足三个条件:
- 必须有一个嵌套函数(内部函数)。
- 内部函数必须引用外部函数中的变量。
- 外部函数的返回值必须是内部函数。
4. 闭包的创建过程
当一个外部函数返回一个内部函数时,Python会自动检测内部函数是否引用了外部函数的变量。如果引用了,Python就会创建一个闭包。闭包不仅包含内部函数的代码,还包含了内部函数引用的外部变量的副本。这意味着,即使外部函数的执行已经结束,内部函数仍然可以访问那些变量。
5. 闭包与变量的生命周期
通常,一个函数的局部变量在函数执行结束时就会被销毁。但是,闭包的一个关键特点是它延长了这些变量的生命周期。通过闭包,即使外部函数已经执行完毕,内部函数仍然可以访问外部函数的变量。
三、示例:创建一个简单的闭包
让我们通过一个例子更详细地解释闭包的概念和创建过程。
# 定义一个外部函数
def make_multiplier(x):
# 定义一个内部函数
def multiplier(n):
# 内部函数使用了外部函数的变量x
return x * n
# 外部函数返回内部函数,这时候创建了一个闭包
return multiplier
# 使用外部函数创建闭包实例
times3 = make_multiplier(3) # 现在times3是一个闭包,记住了x为3
times5 = make_multiplier(5) # times5是另一个闭包,记住了x为5
# 调用闭包
print(times3(10)) # 输出: 30
print(times5(10)) # 输出: 50
在上面的例子中,
make_multiplier
是一个外部函数,而它返回的multiplier
是一个内部函数。multiplier
内部使用了make_multiplier
的参数x
,因此当我们调用times3(10)
时,尽管make_multiplier
的调用已经结束,但是multiplier
还记住了x
是3,并用它来计算结果。
四、闭包的用途
闭包通常用于:
- 创建只有函数能够访问的私有变量。
- 编写只带有一个操作的小函数的代码。
- 实现延时计算。
五、闭包的应用场景
1. 数据封装和信息隐藏
闭包可以提供一种封装数据的方式,通过使用闭包,可以隐藏状态而不必使用类。这可以帮助你保持状态的私有性,同时提供公共接口来操作这些私有数据。
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
counter1 = make_counter()
print(counter1()) # 输出 1
print(counter1()) # 输出 2
counter2 = make_counter()
print(counter2()) # 输出 1
在这个例子中,每次调用`make_counter`都会创建一个新的闭包,其中包含其自己的独立`count`变量。外部代码无法直接访问`count`变量,它只能通过闭包提供的`counter`函数进行间
2. 保持状态
闭包可以在函数被多次调用时保持变量的状态,即使这个函数在不同的上下文中被调用。
def power_factory(exp):
def power(base):
return base ** exp
return power
square = power_factory(2)
cube = power_factory(3)
print(square(4)) # 输出 16
print(cube(4)) # 输出 64
这里,`make_printer`函数创建了闭包,记住了传递给它的消息`msg`。即使`make_printer`函数的执行已经结束,闭包内的`printer`函数仍然能够访问并打印保存的消息。
3. 函数工厂
闭包可以用来创建一系列类似的函数,或者在运行时动态地创建函数。
def power_factory(exp):
def power(base):
return base ** exp
return power
square = power_factory(2)
cube = power_factory(3)
print(square(4)) # 输出 16
print(cube(4)) # 输出 64
在这个例子中,`power_factory`根据传递给它的指数`exp`创建了一个新的闭包。这个闭包`power`拥有对`exp`的引用,允许我们为不同的指数创建不同的函数。
4. 延迟计算
闭包可以用来延迟计算的执行,这在处理昂贵的计算任务或配置时特别有用。
def lazy_evaluation(number):
def eval():
return number * number
return eval
lazy_square = lazy_evaluation(10)
# 计算被延迟,直到我们调用闭包
print(lazy_square()) # 输出 100
这里,`lazy_evaluation`函数返回的闭包`eval`延迟了对`number`的平方计算。只有在实际需要结果时调用闭包,计算才会执行。
六、结论
标签:闭包,函数,power,python,make,理解,multiplier,变量 From: https://blog.csdn.net/qq_26917905/article/details/137198426闭包在Python中是一个非常有用的特性,允许我们编写更加简洁和模块化的代码。通过闭包,我们可以轻松创建能够保持状态的函数,而不需要依赖于对象或者全局变量。