欢迎光临
我们一直在努力

Python 中的闭包(Closure)

   闭包是指在一个嵌套函数中,内部函数引用了外部函数的变量,并且外部函数返回了内部函数。闭包会“记住”外部函数的变量,即使外部函数已经执行完毕。

一、什么是闭包

1. 基本结构

def outer(x):
def inner(y):
return x + y
return inner

# 创建闭包
add_5 = outer(5)
result = add_5(3)
print(result) # 8

关键要素:

  • 存在嵌套函数(inner)

  • 内部函数引用了外部函数的变量(x)

  • 外部函数返回了内部函数

  • 2. 闭包的本质

    def outer(x):
    def inner(y):
    return x + y
    return inner

    add_5 = outer(5)
    add_10 = outer(10)

    print(add_5(3)) # 8
    print(add_10(3)) # 13

    # 查看闭包捕获的变量
    print(add_5.__closure__) # (<cell at 0x…: int object at 0x…>,)
    print(add_5.__closure__[0].cell_contents) # 5

    二、闭包的特点

    1. 记住外部变量的值

    def counter():
    count = 0

    def increment():
    nonlocal count
    count += 1
    return count

    return increment

    c1 = counter()
    c2 = counter()

    print(c1()) # 1
    print(c1()) # 2
    print(c1()) # 3
    print(c2()) # 1(独立的闭包,有自己的 count)

    2. 延迟计算

    def make_power(exponent):
    def power(base):
    return base ** exponent
    return power

    square = make_power(2) # 平方函数
    cube = make_power(3) # 立方函数

    print(square(5)) # 25
    print(cube(5)) # 125

    三、闭包的实现原理

    1. __closure__ 属性

    每个闭包函数都有一个 __closure__ 属性,存储捕获的外部变量。

    def outer(x, y):
    z = 100
    def inner():
    return x + y + z
    return inner

    func = outer(10, 20)

    # 查看闭包捕获的变量
    print(func.__closure__)
    # (<cell at 0x…: int object at 0x…>,
    # <cell at 0x…: int object at 0x…>,
    # <cell at 0x…: int object at 0x…>)

    # 查看捕获的值
    for cell in func.__closure__:
    print(cell.cell_contents) # 10, 20, 100

    2. __code__.co_freevars 自由变量

    def outer(x):
    def inner(y):
    return x + y
    return inner

    func = outer(10)
    print(func.__code__.co_freevars) # ('x',)
    print(func.__code__.co_varnames) # ('y',)

    四、闭包 vs 类

    闭包在某些场景可以作为轻量级的替代方案。

    # 使用闭包实现计数器
    def counter_closure():
    count = 0
    def increment():
    nonlocal count
    count += 1
    return count
    return increment

    # 使用类实现计数器
    class CounterClass:
    def __init__(self):
    self.count = 0

    def increment(self):
    self.count += 1
    return self.count

    # 闭包更简洁
    c1 = counter_closure()
    print(c1()) # 1

    # 类更明确
    c2 = CounterClass()
    print(c2.increment()) # 1

    特性闭包类
    代码量
    可读性 简单场景好 复杂场景好
    状态 通过 nonlocal 修改 通过 self 修改
    方法数量 单个函数 可以有多个方法
    适用场景 简单状态保存 复杂业务逻辑

    五、调试闭包

    def outer(x, y):
    z = 100

    def inner(w):
    return x + y + z + w

    return inner

    func = outer(10, 20)

    # 1. 查看闭包中捕获的变量名
    print(func.__code__.co_freevars) # ('x', 'y', 'z')

    # 2. 查看闭包中捕获的值
    for cell in func.__closure__:
    print(cell.cell_contents) # 10, 20, 100

    # 3. 查看函数的局部变量名
    print(func.__code__.co_varnames) # ('w',)

    六、其他

    特性说明
    定义 函数+捕获的外部变量
    条件 嵌套函数 + 引用外部变量 + 返回内部函数
    捕获方式 按引用捕获(不是按值)
    内存 外部变量不会随函数结束而销毁
    访问 读:直接访问;写:需要 nonlocal
    常见应用 装饰器、计数器、缓存

    核心:

  • 闭包会记住外部函数的变量

  • 每次调用外部函数都会创建新的闭包实例

  • 修改外部变量需要 nonlocal 关键字

  • 闭包是装饰器的底层实现原理

  • 赞(0)
    未经允许不得转载:171主机测评 » Python 中的闭包(Closure)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址