Python的可變與不可變資料型別
阿新 • • 發佈:2019-01-08
python的可變與不可變資料型別
初學python的時候,可能會有很多疑惑,尤其是最先接觸的所謂的“可變資料型別”和“不可變資料型別”。python與C/C++不一樣,它的變數使用有自己的特點,當初學python的時候,一定要記住“一切皆為物件,一切皆為物件的引用”這句話,其實這個特點類似於JAVA,所以在python裡面大家也不用擔心類似於C/C++中的指標的複雜問題。下面本文將對python裡面的“可變資料型別”和“不可變資料型別”進行分析。 首先,我們需要知道在python中哪些是可變資料型別,哪些是不可變資料型別。可變資料型別:列表list和字典dict;不可變資料型別:整型int、浮點型float、字串型string和元組tuple。(1)不可變資料型別分析。先來看一段程式:
>>> x = 1 >>> id(x) 31106520 >>> y = 1 >>> id(y) 31106520 >>> x = 2 >>> id(x) 31106508 >>> y = 2 >>> id(y) 31106508 >>> z = y >>> id(z) 31106508
>>> x += 2
>>> id(x)
31106484
上面這段程式都是對不可變資料型別中的int型別的操作,id()檢視的是當前變數的地址值。我們先來看x = 1和y = 1兩個操作的結果,從上面的輸出可以看到x和y在此時的地址值是一樣的,也就是說x和y其實是引用了同一個物件,即1,也就是說記憶體中對於1只佔用了一個地址,而不管有多少個引用指向了它,都只有一個地址值,只是有一個引用計數會記錄指向這個地址的引用到底有幾個而已。當我們進行x = 2賦值時,發現x的地址值變了,雖然還是x這個引用,但是其地址值卻變化了,後面的y = 2以及z = y,使得x、y和z都引用了同一個物件,即2,所以地址值都是一樣的。當x和y都被賦值2後,1這個物件已經沒有引用指向它了,所以1這個物件佔用的記憶體,即31106520地址要被“垃圾回收”,即1這個物件在記憶體中已經不存在了。最後,x進行了加2的操作,所以建立了新的物件4,x引用了這個新的物件,而不再引用2這個物件。
從上面的過程可以看出,不可變資料型別的優點就是記憶體中不管有多少個引用,相同的物件只佔用了一塊記憶體,但是它的缺點就是當需要對變數進行運算從而改變變數引用的物件的值時,由於是不可變的資料型別,所以必須建立新的物件,這樣就會使得一次次的改變建立了一個個新的物件,不過不再使用的記憶體會被垃圾回收器回收。
(2)可變資料型別分析。下面同樣先看一段程式。
>>> a = [1, 2, 3]
>>> id(a)
41568816
>>> a = [1, 2, 3]
>>> id(a)
41575088
>>> a.append(4)
>>> id(a)
41575088
>>> a += [2]
>>> id(a)
41575088
>>> a
[1, 2, 3, 4, 2]
從上面的程式中可以看出,進行兩次a = [1, 2, 3]操作,兩次a引用的地址值是不同的,也就是說其實建立了兩個不同的物件,這一點明顯不同於不可變資料型別,所以對於可變資料型別來說,具有同樣值的物件是不同的物件,即在記憶體中儲存了多個同樣值的物件,地址值不同。接著來看後面的操作,我們對列表進行新增操作,分別a.append(4)和a += [2],發現這兩個操作使得a引用的物件值變成了上面的最終結果,但是a引用的地址依舊是41575088,也就是說對a進行的操作不會改變a引用的地址值,只是在地址後面又擴充了新的地址,改變了地址裡面存放的值,所以可變資料型別的意思就是說對一個變數進行操作時,其值是可變的,值的變化並不會引起新建物件,即地址是不會變的,只是地址中的內容變化了或者地址得到了擴充。下圖對這一過程進行了圖示,可以很清晰地看到這一過程。