Python 的闭包

什么是闭包?

闭包, 英文为closure.
首先, 闭包是一种特殊的函数. 特殊之处在于它包含了非本地也非全局的自由变量.

def outer_fn():
    outer_var = []
    def inner_fn(val):
        outer_var.append(val)
        return sum(outer_var) * 1.0 / len(outer_var)
    return inner_fn

在上面的代码中, inner_fn就是一个闭包函数. 对inner_fn来说, outer_var既非它的本地变量, 也非全局变量, 而是outer_fn的本地变量.

实现原理

按照道理来说, outer_fn的本地变量在程序退出函数体后会被自动销毁回收, 但因为outer_varinner_fn内被引用了, 所以它不会被销毁, 而是成为一个自由变量. 可是, 在执行inner_fn的主体代码时, outer_var存储在哪呢? 在fn对象的__closure__属性里:

fn = outer_fn()
print(fn(10))
print ('fn.__closure__:', fn.__closure__[0].cell_contents)
print(fn(20))
print ('fn.__closure__:', fn.__closure__[0].cell_contents)

输出为:

10.0
fn.__closure__: [10]
15.0
fn.__closure__: [10, 20]

有什么用?

也许有用, 例如在修饰器中, 但并非不可缺少. 引入闭包实际是给函数对象引入了状态, 然后呢, 导致相同的输入不一定能得到相同的输出, 感觉有点别扭. 所以, 如果需要保存状态, 可以通过面向对象方式来实现. 例如上面的代码可使用class 封装:

class Cls():
    def __init__(self):
        self.var = []

    def fn(self, val):
        self.var.append(val)
        return sum(self.var) * 1.0 / len(self.var)

inst = Cls()
print(inst.fn(10))
print(inst.fn(20))

这样虽然可能需要多敲几个字母, 但代码的可维护性大大增加. 所以, 闭包对于我来说, 了解下概念就行, 尽量不用.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值