python闭包

[1] x += 1 和 x = x + 1 区别

这里写图片描述

两者id(对象的内存地址)和初始x的id均不相同。说明对x进行改变时,x引用的对象在发生改变。x就像衣服上的标签,引用的对象就是衣服。试图改变x时,相当于把x标签从A衣服上撕下来,粘在B衣服上。
作为不可变对象,x += 1和 x = x + 1没有什么区别

[2]s += [1]、s += s [1]和s.append(1)区别

这里写图片描述

我们发现前两者id和初始s的id值相等,s引用的对象没有发生变化。而在s = s + [1]情况下,id值发生改变,s引用的对象发生变化。
前两者的赋值流程:

这里写图片描述这里写图片描述这里写图片描述

s是对一个list的引用,使用s.append()和s+=[]都是在此list末端添加一个值。

在s = s + [1]情况下,’=’前面的s是对(s +[1])的引用(’=’后面s是初始定义的s),和t = s + [1]没有任何区别,像x=x+1一样,将s标签贴到了其他对象上。

因此,我们可以知道无论是操作可变对象还是不可变对象时,x = x + 1(或s = s +[1])这种情况,x的引用的对象会改变(x->A对象变为x->B对象)。

对于不可变对象,x+=1会改变引用的对象。对于可变对象,s += [1]为就地存储,不改变引用的对象。

[3]作用域

现在可以说说另一个东西。

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

前三种情况,变量未绑定。在一个函数里,解释器查找变量的顺序是局部变量–>闭包环境–>全局变量–>内置变量(LEDB),且前者会覆盖后面的变量。在func函数里,解释器发现等号前的x(或s),x(或s)又引用了(x+1),x为自身,肯定是矛盾的,所以解释器就报错兰。然而s.append()一点问题都没有,是因为s是全局变量。

流程:
这里写图片描述这里写图片描述

这里写图片描述

Func里locals()为空也说明了s不是func的局部变量。Globals()函数说明s是全局变量。

[4]闭包

这里写图片描述

s是make_func的局部变量,locals里有s是正常的。但按照上面所说,func的locals应该不存在s。python设置了一个闭包机制,将func及其同级的变量保存在一个地方,形成闭包。s为自由变量。在python2.7中,如果s为不可变变量,则会报错。s为可变变量则形成闭包。在python3中,添加了nonlocal关键字,声明s为自由变量。用法和globals相似。再也不用担心s是不是可变变量兰。

这里写图片描述

这里写图片描述

可以看看dir(f),了解f的内部对象。f.code.co_freevars为(‘s’,)。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值