全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-19 8 分钟 ✍️ juanwangdev

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 关键字修改闭包变量
  • 变量捕获是引用而非值拷贝
  • 注意循环中的延迟绑定陷阱
  • 闭包适合简单状态管理,类适合复杂场景
  • 闭包实现数据封装和函数工厂

📝 发现内容有误?点击此处直接编辑

← 上一篇 Python 函数装饰器原理
下一篇 → Python 高阶函数
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库