问题: 如何写一个简单的闭包函数,举例说明?

👇 点击展开/折叠 面试背诵模板(建议先背这个) 闭包函数的标准写法:外层函数定义并返回内层函数,内层函数引用外层函数的局部变量。 示例:def outer(x): def inner(y): return x + y; return inner。 调用 add5 = outer(5); add5(3) 返回 8。内层函数 inner 捕获了外层变量 x,即使 outer 执行完毕,x 仍被 inner 保留,实现状态记忆。

闭包三步走结构

步骤 代码位置 说明
① 定义外层函数 def outer(x): 外层函数接收外部参数或定义局部变量
② 定义内层函数 def inner(y): return x + y 内层函数引用了外层变量 x(自由变量)
③ 返回内层函数 return inner 外层函数将内层函数对象返回,供外部调用

完整代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def outer(x):
def inner(y):
return x + y
return inner

# 创建闭包:捕获 x = 5
add5 = outer(5)

# 调用闭包:传入 y = 3,使用捕获的 x = 5
print(add5(3)) # 输出 8
print(add5(10)) # 输出 15

# 另一个独立的闭包:捕获 x = 100
add100 = outer(100)
print(add100(1)) # 输出 101

验证闭包捕获了什么

1
2
print(add5.__closure__)          # (<cell at 0x...: int object at 0x...>,)
print(add5.__closure__[0].cell_contents) # 5 → 捕获的变量值

闭包 vs 普通函数对比

维度 普通函数 闭包
参数来源 仅来自调用时传入 调用时传入 + 捕获的外层变量
状态保持 每次调用独立,无记忆 捕获的变量持久存在,可累积状态
数据隔离 全局变量可能冲突 每个闭包独立捕获,互不干扰

闭包捕获变量的注意事项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# ⚠️ 注意:捕获的是变量引用,不是值
def outer():
funcs = []
for i in range(3):
def inner():
return i
funcs.append(inner)
return funcs

f1, f2, f3 = outer()
print(f1()) # 2,不是 0!因为 i 最终是 2,三个闭包共享同一个 i

# ✅ 解决方案:用默认参数冻结当前值
def outer():
funcs = []
for i in range(3):
def inner(i=i): # 默认参数在定义时求值,锁定当前 i
return i
funcs.append(inner)
return funcs

f1, f2, f3 = outer()
print(f1()) # 0 ✅
print(f2()) # 1 ✅

修改捕获的变量:nonlocal 声明

1
2
3
4
5
6
7
8
9
10
11
def counter():
count = 0
def increment():
nonlocal count # 声明 count 不是局部变量,而是外层变量
count += 1
return count
return increment

c = counter()
print(c()) # 1
print(c()) # 2