在平常的工做和學習中,常常會遇到「不可變對象 」 相關的問題,可是隨着接觸Python這門語言的時間愈來愈多,遇到的坑愈來愈奇怪。我不由產生了一個疑問:不可變對象真的不可變嗎?python
咱們知道元組就是"不可變對象",當你想嘗試給一個元組賦值的時候,它會報錯:bash
>>> my_tuple = ("python", "dict", "is", "good")
>>> my_tuple[3] = "excellent"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
複製代碼
請注意報錯的語言: "does not support item** assignment** ", 元組對象不支持賦值操做。app
讓咱們來看看下面這樣的操做:學習
>>> int_tuple = ([6,5,30], [2,3,65], [111])
>>> int_tuple[2] += [22,33]
Traceback (most recent call last): File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> int_tuple([6, 5, 30], [2, 3, 65], [111, 22, 33])
複製代碼
儘管報了一個錯,可是它變量的值已經被改變了。spa
其實,這裏主要是由於 += 操做對於「不可變對象」會產生新的變量並綁定到原有變量上。可是又因爲+=中的"="號,執行了一次對元組對象的賦值操做,這是不容許的,所以報了錯,但新的對象已經被綁定到了原有變量中,所以咱們能夠看到變量的值發生了改變。excel
還有一種狀況是這樣的:code
>>> int_tuple = ([6,5,30], [2,3,65], [111])
>>> int_tuple[2].append(123123)
>>> int_tuple
([6, 5, 30], [2, 3, 65], [111, 123123])
複製代碼
這裏徹底沒有報錯,爲何呢?由於append並不涉及到賦值操做,元組只是不容許賦值,並無不容許append和extend啊,因此稱元組爲「不可變對象」 實在是太不嚴謹了!cdn
其實若是你知道元組中存放的是元素所對應的地址(ID),就好理解多了,append和extend僅僅是修改了列表的元素,而列表自己的ID並無發生變化,只有當賦值操做執行的時候,ID纔會發生變化,而這種狀況是元組不容許發生的。對象
# append 不會發生地址變化
>>> int_tuple = ([1], [2], [3])
>>> id(int_tuple[1])
2729947990600
>>> int_tuple[1].append(22)
>>> id(int_tuple[1])
2729947990600
複製代碼
所以,要避免踩上這些坑,忘掉元組是「不可變對象」這樣不嚴謹的表述形式(固然從地址的角度來說它是對的,元組內部全部元素的ID都不可變),請這樣記:元組是不可賦值對象。教程
咱們的文章到此就結束啦,若是你但願咱們今天的Python 教程,請持續關注咱們,若是對你有幫助,麻煩在下面點一個贊/在看哦
有任何問題均可以在下方留言區留言,咱們都會耐心解答的!Python實用寶典 (pythondict.com)
不僅是一個寶典
歡迎關注公衆號:Python實用寶典
原文來自Python實用寶典:Python 不可變對象真的不可變嗎?