Python中的+=


 

引出

今天在運行之前寫的一個Python腳本時,發生了一個奇怪的現象(我怎么老遇到奇怪的現象~~)。當時的代碼大概長這樣:

a = [1, 2, 3]
b = [4, 5, 6]
# ...一大段邏輯
c = a
c += b
# ...一大段邏輯
# 在這里,a變成了[1, 2, 3, 4, 5, 6]

首先,上面的代碼一個函數過於長了,實在不像話

當時的情景是這樣的,程序並沒有想我預期中一樣運行。我找了半天,沒有找到對a變量的修改或賦值操作。

最終,發現了藏在中間的c變量,因為是列表對象的引用賦值,所以直接修改了a變量。我將兩個變量的地址打印出來,確實是這樣的。

本來,查到這里基本上破案了。也應該沒有后續了

但我上網查了一下,有人說用 =+就不會出現這種情況,我輕蔑的笑了,有什么區別么?不信邪的我試了一下。

What?誰能告訴我發生了什么?

探究

根據我的推測,必然是+=操作改變的是原對象,=+操作返回了新的對象。嘗試一下:

果不其然。在此破案。

解惑

都知道Python的運算符重載操作,加法調用的是__add__方法,+=調用的是__iadd__方法。既然產生這個現象,那一定是list對兩個方法的實現不同咯。

嘗試自己動手測試,寫一個Test類,實現兩個重載方法:

分別調用+==+

可以看到,都是新的值。如果修改一下方法的實現:

再測試就會發下,兩個運算返回的都是同一個對象。水落石出,Python對兩個不同的運算符使用了不同的實現方法。

一探究竟

那為什么Python會在 +=操作時,直接修改原對象。而=+操作卻要返回新的對象呢?

簡單推測一下,可能Python的作者認為,+=操作是要將后邊的值加到自身上。而+則是兩個值的運算操作。根據表達是也可以看出:

a += b # 這里只涉及兩個變量,將b的內容直接加到a上
c = a + b # 這里涉及到了三個變量,將后兩者內容相加后賦值給新的變量

 


最后,既然+==+的實現不同,那么同理列表的-==-*==*/==/的實現也必然不同。

哦,不好意思,list沒有實現減法和除法的操作。但乘法確實也是這樣。

好吧,之后再進行對象運算符重載時可以參考一下上面的做法,仔細想想還是很合乎邏輯的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM