Python中a += b 並不一定等價於a = a + b

青南發表於2019-01-29

大家經常在一些部落格中看到這樣的說法:

a += 1
複製程式碼

等價於

a = a + 1
複製程式碼

這種說法實際上並不準確。

我們來看一個例子:

>>> a = [1, 2, 3]
>>> a += (4,)
>>> a
[1, 2, 3, 4]

>>> a = [1, 2, 3]
>>> a = a + (4,)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
複製程式碼

這裡報錯了,說明a += ba = a + b並不是完全等價的。

實際上,這是由於+=會首先呼叫左邊這個物件的__iadd__方法,如果沒有__iadd__方法,就會呼叫__add__方法。但是如果直接使用+號,就會直接呼叫__add__方法。而對於字串、數字、浮點數這種不可變物件,他們沒有__iadd__方法,所以對他們來說,a += ba = a + b是等價的。

但是列表是一個可變的容器,它內部是有__iadd__這個方法。對於列表來說,它的__iadd__方法的原型如下:

    def __iadd__(self, values):
        self.extend(values)
        return self
複製程式碼

這一段程式碼你可以在這裡看到:github.com/python/cpyt…

所以說,當你使用+=連線列表和元組的時候,本質上是列表使用extend把元組的內容新增進去。這樣是不會報錯的:

>>> a = [1, 2, 3]
>>> a.extend((4,))
>>> a
[1, 2, 3, 4]
複製程式碼

相關文章