〇、普通嵌套函数
在python中,普通的嵌套函数是指定义在另一个函数内部的函数。它是一个纯粹的语法结构概念。只需要满足“函数定义在函数内部”这一条件就可以了。
嵌套函数:在一个函数的函数体内部使用def关键字定义的函数。
def outer(): print("外部函数开始") # 这就是一个普通的嵌套函数 def inner(): print("内部函数执行") inner() # 在外部函数内调用内部函数 print("外部函数结束") outer()一、闭包的定义
在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们就把这个使用外部函数变量的内部函数称为闭包。形成闭包的三个条件:
- 嵌套函数:在函数嵌套的前提下
- 引用外部变量:内部函数使用了外部函数的变量(还包括外部函数的参数)
- 外部函数返回内部函数:外部函数将内部函数作为返回值返回
def outer_func(message): # message 是外部函数的局部变量 def inner_func(): # 内部函数引用了外部函数的message变量 print(f"消息内容:{message}") # 返回内部函数对象(注意不是调用) return inner_func # 创建闭包 my_closure = outer_func("Hello!") # 此时outer_func已经执行解释,但message变量并未销毁 my_closure()在闭包内可以使用nonlocal关键字来修改外部函数的变量。
def outer_func(message): # messge是外部函数的局部变量 def inner_func(new_message=None): nonlocal message # 声明message来自外部函数作用域,而非创建新的局部变量 if new_message is not None: message = new_message print(f"消息内容:{message}") return inner_func # 创建闭包 my_closure = outer_func("Hello!") my_closure() # 输出:消息内容:Hello! my_closure("hi") # 输出:消息内容:hi my_closure() # 输出:消息内容:hi 此时message的状态已经内持久化修改了二、普通嵌套函数和闭包的区别
判断一个函数是不是闭包,可以通过检查函数的__closure__属性
print(my_closure.__closure__) # 输出类似: (<cell at 0x...: str object at 0x...>,) # 如果为 None,则不是闭包| 特征 | 普通嵌套函数 | 闭包 |
|---|---|---|
| 定义位置 | 函数内部 | 函数内部 |
| 引用外部变量 | 不一定需要 | 必须引用 |
| 返回到外部 | 通常只在内部调用 | 必须返回或传递出去 |
| 生命周期 | 随外部函数调用结束而销毁 | 外部函数结束后仍可存活 |
__closure__属性 | None | 包含 cell 对象的元组 |
| 本质 | 语法结构 / 作用域组织手段 | 数据对象(函数+环境) |
闭包 = 函数 + 其引用的外部环境。它是 Python 实现高阶编程、函数式编程风格的重要基石。
三、闭包有什么用?
闭包在python中的核心价值在于它提供了一种轻量化的状态保持与行为定制机制。相比于使用类Class或者全局变量,闭包在特定场景下更加简洁、安全且符合函数式编程范式。以下是闭包的主要使用场景:
- Python 的装饰器本质上就是闭包。它允许你在不修改原函数代码的前提下,动态地添加日志、权限校验、缓存、重试等功能。
- 替代简单的类进行轻量级状态封装。当你只需要一个带有状态的函数,而不需要完整的面向对象设计时,闭包比类更简洁。
- 用在回调函数与延迟执行。在事件驱动编程、异步任务、GUI 编程中,闭包可以让回调函数“记住”创建时的上下文,避免传递大量参数或使用全局变量。