a+=b
a=a+b
针对于int型。
>>> a=1
>>> b=a
>>> a+=1
>>> a,b
(2, 1)
>>> a=1
>>> b=a
>>> a=a+1
>>> a,b
(2, 1)
>>> a=[1,2,3,4]
>>> b=a
>>> a+=[5]
>>> a,b
([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])
通俗地讲,类型为int时,a和b是“不一样的”;类型为list时,a和b是“一样的”。术语叫做immutable和mutable。两者是有区别的,而这种区别只出现在可变对象上,当两个对象是可变对象时,两个是有区别的;当两个对象是不可变对象时,两个没区别。是什么原因造成了两者的区别呢?
+= 操作调用 __iadd__方法,没有该方法时,再尝试调用__add__方法
__iadd__方法直接在原对象a1上进行更新,该方法的返回值为None
+ 操作调用__add__方法
__add__方法会返回一个新的对象,原对象不修改,因为这里 a1被重新赋值了,a1指向了一个新的对象,所以出现了文章开头a1不等于a2的情况。
也就是在+=的情况下,a还是原来的a,和b“一样”,直接在原对象a和b上进行修改;在= +的情况下,a已经不是原来的a了,和b“不一样”。是a+b的结果产生的新对象赋值给a。
为什么前面我说这种差异只会发生的可变对象身上?因为对于不可变对象,根本没有 __iadd__方法,所以+=和+的效果是一样的,因为调的都是 __add__ 方法。
b=copy.deepcopy(a)才是进行我们通常期望的“拷贝”。类似于java的clone()函数。
copy.copy和copy.deepcopy还是有区别的,请看相关文章。