Python运算符+与+=的那些事

这两个运算符很多语言都提供了,好像也没啥好说的,不就是像下面这样子用嘛。

>>> x = 3
>>> y = x+6
>>> y
9
>>> x += 6
>>> x
9

+运算符得到新对象,当然也可以在原对象值的基础上进行增加,例如x = x+6;而+=总是修改原来的对象值。

但如果深入研究的话,情况似乎还是有些出乎意料的,看下面的代码:

>>> x = 3
>>> id(x)
1494131872
>>> x += 6
>>> id(x)
1494132064

其中内置函数id()用来返回一个对象的内存地址。那么上面的代码说明了什么呢?执行+=运算之后,x的内置地址发生了变化。究其原因,在于Python采用的是基于值的自动内存管理模式。变量中不直接存储值,而是存储值的引用,也就是值在内存中的地址。上面代码的执行过程如图所示,在执行x += 6时,首先把原来的3取出来,加上6得到9,把9放到内存中,最后再让x来指向这个新地址。

然而,当+和+=作用于列表时,情况又有所不同。

>>> x = [1, 2, 3]
>>> id(x)
1668306802824
>>> x = x + [4]
>>> id(x)
1668306565768
>>> x += [5]
>>> id(x)
1668306565768

发现了什么?+=作用于列表时居然是原地操作,类似于列表的append()方法。确实是这样的。在类的设计中,特殊方法__iadd__()对应于+=运算符,而+运算符则对应于特殊方法__add__(),有例为证:

>>> class Test:
     def __init__(self, v):
          self.__value = [v]
     def __add__(self, vv):
          return Test(self.__value[0] + vv)
     def __iadd__(self, vv):
          self.__value.append(vv)
          return self
     def show(self):
          return self.__value

 
>>> t = Test(3)
>>> t.show()
[3]
>>> id(t)
1668306894744
>>> tt = t+6
>>> tt.show()
[9]
>>> id(tt)
1668306197640
>>> t += 6
>>> t.show()
[3, 6]
>>> id(t)
1668306894744

既然这样的话,那么列表对象的+=也就是__iadd__()会设计成什么样子,就都是可以理解的了。

最后,如果元组中含有子列表,+=会有一个坑,详见Python编程中一定要注意的那些“坑”(一)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dongfuguo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值