直接回答:闭包是"引用了自由变量的函数"——内层函数使用了外层函数的局部变量,外层函数返回内层函数后,这些变量不会随外层函数结束而销毁,而是跟随内层函数一起存活。
示例:
def make_counter():
count = 0
def inc():
nonlocal count
count += 1
return count
return inc
c = make_counter()
c(); c() # 返回 1、2,count 被"私有"保存
展开解析:主要用途——数据隐藏(count 外界访问不到,等效私有字段)、装饰器、回调函数、延迟计算与函数工厂。与类的共同点:二者都是"状态 + 行为"的封装体,只是方向相反——闭包是携带状态的单个函数,对象是携带方法的状态集合。只封一个操作时闭包更轻量;需要多方法、继承、协议时用类。
易错点:
- 修改外层变量必须声明
nonlocal(Python 2 需用列表等可变对象绕行); - 循环中定义闭包的延迟绑定陷阱:所有闭包共享循环变量的最终值,应通过默认参数固定:
lambda x, i=i: x + i。
追问:闭包变量存在 __closure__ 单元格中、装饰器如何依赖闭包实现。