Python 闭包函数
闭包是内部函数引用外部函数变量的结构,变量被捕获并延续存在。
闭包定义
Python
def outer(x):
def inner(y):
return x + y # inner 引用 outer 的变量 x
return inner
add_5 = outer(5) # x = 5 被捕获
print(add_5(3)) # 8
print(add_5(10)) # 15
# x 在 outer 执行后仍然存在
add_10 = outer(10)
print(add_10(3)) # 13
closure 属性
Python
def outer(x):
def inner():
return x
return inner
func = outer(42)
# 查看闭包捕获的变量
print(func.__closure__) # (<cell at ...>,)
print(func.__closure__[0]) # <cell at ...>
print(func.__closure__[0].cell_contents) # 42
闭包应用场景
函数工厂
Python
def make_multiplier(factor):
def multiplier(value):
return value * factor
return multiplier
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
状态保持
Python
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
c = counter()
print(c()) # 1
print(c()) # 2
print(c()) # 3
数据封装
Python
def secret_holder(secret):
def get_secret(password):
if password == 'admin':
return secret
return 'Access denied'
return get_secret
holder = secret_holder('my_secret')
print(holder('wrong')) # Access denied
print(holder('admin')) # my_secret
nonlocal 关键字
修改闭包中的外部变量。
Python
def outer():
count = 0
def inner():
nonlocal count # 声明使用外部变量
count += 1
return count
return inner
counter = outer()
print(counter()) # 1
print(counter()) # 2
# 不使用 nonlocal 会报错
def bad_outer():
count = 0
def bad_inner():
count += 1 # UnboundLocalError
return count
return bad_inner
变量捕获机制
Python
def example():
values = [1, 2, 3]
def get_values():
return values # 捕获整个列表引用
def append_value(v):
values.append(v) # 修改捕获的列表
return get_values, append_value
getter, setter = example()
print(getter()) # [1, 2, 3]
setter(4)
print(getter()) # [1, 2, 3, 4]
闭包陷阱
循环变量延迟绑定
Python
def create_multipliers():
multipliers = []
for i in range(5):
def multiplier(x):
return x * i # i 延迟绑定,最终都是 4
multipliers.append(multiplier)
return multipliers
funcs = create_multipliers()
print(funcs[0](10)) # 40(期望 0)
print(funcs[1](10)) # 40(期望 10)
# 解决方案:立即绑定
def create_multipliers_fixed():
multipliers = []
for i in range(5):
def multiplier(x, n=i): # 默认参数立即绑定
return x * n
multipliers.append(multiplier)
return multipliers
闭包 vs 类
Python
# 闭包实现
def make_counter():
count = 0
def inc():
nonlocal count
count += 1
return count
def dec():
nonlocal count
count -= 1
return count
return {'inc': inc, 'dec': dec}
counter = make_counter()
print(counter['inc']()) # 1
print(counter['inc']()) # 2
# 类实现
class Counter:
def __init__(self):
self.count = 0
def inc(self):
self.count += 1
return self.count
def dec(self):
self.count -= 1
return self.count
c = Counter()
print(c.inc()) # 1
print(c.inc()) # 2
要点总结
- 闭包 = 内部函数 + 引用的外部变量
__closure__属性存储捕获的变量nonlocal关键字修改闭包变量- 变量捕获是引用而非值拷贝
- 注意循环中的延迟绑定陷阱
- 闭包适合简单状态管理,类适合复杂场景
- 闭包实现数据封装和函数工厂
📝 发现内容有误?点击此处直接编辑