Python 闭包

闭包:

闭包(closure)是函数式编程的重要的语法结构。不同的语言实现闭包的方式不同。Python以函数对象为基础,为闭包这一语法结构提供支持的 (我们在特殊方法与多范式中,已经多次看到Python使用对象来实现一些特殊的语法)。Python一切皆对象,函数这一语法结构也是一个对象。在函数对象中,我们像使用一个普通对象一样使用函数对象,比如更改函数对象的名字,或者将函数对象作为参数进行传递。

  • 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。(相当于给内部函数起别名)
  • 实现规则:
    定义内部函数
    外部函数必须有返回值,而且返回值必须为内部函数对象
# 内嵌的函数
# 1.内部函数引用了外部函数的变量 2.外部函数返回的是内部函数的引用
def outerfunc():
    x = 100   # 局部变量
    def innerfunc():
        z = x+1
        return z
    return innerfunc

# 函数的局部变量的生命周期,在函数执行完之后,局部变量的内存会被释放
# 但是python中的闭包结构,不一样,他提供了机制保存内部函数引用到的外部函数里的临时变量的对象
f = outerfunc()
print(f())

小问题

def outer():
    return [lambda x: i * x for i in range(4)]

print([m(2) for m in outer()])

结果为:[6,6,6,6],而期望是[0,2,4,6]
修改后:

def outer():
    return [lambda x,i=i: i * x for i in range(4)]

print([m(2) for m in outer()])

#使用生成器
def outer():
    for i in range(4):
        yield lambda x : i*x

print([m(2) for m in outer()])

结果为:[0, 2, 4, 6]
为什么会出现这种问题:
原因是Python的闭包是延迟绑定(late binding)的。这表明在闭包中使用的变量直到内层函数被调用的时候才会被查找。结果是,当调用multipliers()返回的函数时,i参数的值会在这时被在调用环境中查找。所以,无论调用返回的哪个函数,for循环此时已经结束,i等于它最终的值3。因此,所有返回的函数都要乘以传递过来的3,因为上面的代码传递了2作为参数,所以他们都返回了6(即,3 * 2)

注:参考 https://blog.csdn.net/x_r_su/article/details/54618808

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值