Python 深入学习局部函数和闭包函数

目录

局部函数与闭包函数的关联

变量捕获与状态保留

应用场景的交集与差异

闭包的本质

局部函数示例

闭包函数示例



局部函数和闭包函数之间存在着密切的联系,同时也有一些本质的区别。

局部函数与闭包函数的关联

局部函数(Nested Function)

也称嵌套函数,指的是在另一个函数内部定义的函数。它作为外部函数的一部分,只能在外部函数的上下文中被调用和访问。

局部函数可以访问外部函数的局部变量和参数,但通常情况下,一旦外部函数执行完毕,这些局部变量就会被销毁。

闭包函数(Closure)

实际上是一种特殊类型的局部函数,它能够“记住”并访问其外部函数的局部变量和参数,即使在外部函数已经返回之后。

闭包的关键在于它维持了对外部变量的引用,从而能够在外部函数的生命周期结束后继续访问这些变量。

变量捕获与状态保留

局部函数通常不涉及对外部作用域变量的长期保留。它只是简单地借用外部变量的值进行计算或处理,当外部函数执行完毕,局部变量的生命周期也就结束了。

闭包函数通过创建一个引用链条,使得外部函数的局部变量不会被垃圾回收机制回收,即使外部函数已经执行完毕。这就允许闭包在后续的调用中继续访问和修改这些外部变量,从而实现了状态的保留。

应用场景的交集与差异

交集:两者都可以用来实现代码的模块化,通过将相关的操作封装在一起来提高代码的可读性和可维护性。局部函数和闭包函数都能帮助程序员更好地组织代码结构,减少全局变量的使用,从而降低命名冲突的风险。

差异:闭包特别适用于需要在不同时间点访问和修改共享状态的场景,如计数器、缓存管理、装饰器等。而局部函数更多用于逻辑分段,将大块的代码分解为更小、更易于管理的部分,不一定涉及状态的持久化。

闭包的本质

闭包可以视为局部函数的一种扩展,它利用了作用域链和变量生命周期的特性,提供了一种在函数间传递状态和数据的方式。闭包的核心价值在于它打破了常规的变量作用域限制,使得函数可以拥有“记忆”,这在函数式编程和某些特定的设计模式中极为有用。

局部函数示例

这里我们定义一个函数,该函数内部包含一个局部函数,用于执行某个特定计算任务,但不涉及状态的保留。

def outer_function(x):
    """
    这是一个包含局部函数的外部函数。
    它定义了一个局部函数inner_function来执行计算。
    """
    def inner_function(y):
        """这是一个局部函数,用于计算x和y的和。"""
        return x + y  # 访问了外部函数的变量x,并与传入的y相加
    
    result = inner_function(10)  # 调用局部函数并传递参数
    return result

# 调用外部函数
output = outer_function(5)
print(output)  # 输出结果为15

在这个例子中,inner_function是一个局部函数,它只能在outer_function内部被访问和调用。它能够访问外部函数outer_function的参数x,但是当outer_function执行完毕后,inner_function就不再可用。

闭包函数示例

通过一个闭包的例子来展示如何在函数执行结束后仍然保留对外部变量的访问。

def counter_factory(start):
    """
    这个工厂函数返回一个闭包函数。
    闭包函数能够记住start的值,并在此基础上进行计数。
    """
    count = start  # 这个变量被闭包记住

    def counter():
        """闭包函数,每次调用都返回递增的计数。"""
        nonlocal count
        count += 1
        return count

    return counter  # 注意这里返回的是counter函数本身,而不是调用它

# 创建一个从1开始的计数器
counter1 = counter_factory(1)

print(counter1())  # 输出2
print(counter1())  # 输出3
print(counter1())  # 输出4

# 创建另一个从10开始的计数器,演示闭包独立保存状态的能力
counter2 = counter_factory(10)

print(counter2())  # 输出11
print(counter2())  # 输出12

图片

在这个例子中,counter_factory函数返回了一个闭包函数counter。虽然counter函数在counter_factory执行完毕后仍然可用,但它“记得”了创建时start的值,并且每次调用都会基于这个初始值进行计数,展示了闭包的“记忆”特性。每个由counter_factory创建的闭包实例都保留了自己的状态,互不影响。

字典键值对找不到?Python魔法方法__missing__来帮你!-CSDN博客
Humanize,一个很有人情味的 Python 库_python humanize-CSDN博客
Python自定义接口,也能玩得这么花-CSDN博客

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图灵学者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值