1. 程式人生 > >【python基礎】可變型別與不可變型別

【python基礎】可變型別與不可變型別

從上面的文章可以總結出Python中變數名和物件是分離的,通過“=”給變數賦值時,實際上引用變數指向一個物件,而這個物件則是對應記憶體中儲存的一塊資料,取消引用時,Python會回收記憶體。

In [1]: a=100

這個語句執行的意思是:設定記憶體中一塊區域儲存物件“100”,引用變數a指向這個物件。

可以查詢該物件的記憶體地址

In [3]: id(a)
Out[3]: 9095328

再執行語句b=a,又是如何實現呢?

In [2]: b=a
In [6]: id(b)
Out[6]: 9095328

b=a 執行結果是,變數b指向a所指向的物件,這個與c語音中複製記憶體值的機制不一樣。

再思考下一旦賦值後,能不能改變呢?

In [7]: a=100
In [8]: id(a)
Out[8]: 9095328
In [9]: a=200
In [33]: id(a)
Out[33]: 139731596731920

答案是no,從上圖可知重新賦值後,實際是指向了另外一個物件,id結果並不一樣。

這種資料型別就是不可變型別

我們再來看看b的引用物件有沒有發生變化?

In [34]: id(b)
Out[34]: 9095328

可以看出b還是指向以前的物件。這個地方與可變型別不一樣。

再來看看可變的,例如:

In [35]: m=[10,20,"abc"]

In [36]: id(m)
Out[36]: 139731610235208

In [37]: m.append(30)

In [38]: id(m)
Out[38]: 139731610235208

In [39]: m.pop()
Out[39]: 30

In [40]: m
Out[40]: [10, 20, 'abc']

In [41]: id(m)
Out[41]: 139731610235208

可以看出變數m資料修改時,指向的物件一直沒有發生變化。

同樣的 n=m,m發生變化時,n會變化嗎?

In [40]: m
Out[40]: [10, 20, 'abc']

In [41]: id(m)
Out[41]: 139731610235208

In [42]: n=m

In [45]: id(n)
Out[45]: 139731610235208

In [46]: m.insert(1,50)

In [47]: m
Out[47]: [10, 50, 20, 'abc']

In [48]: id(m)
Out[48]: 139731610235208

In [49]: id(n)
Out[49]: 139731610235208

In [50]: n
Out[50]: [10, 50, 20, 'abc']

n的值會隨著m一起發生變化,且指向同一物件。

因此

不可變型別就是指向的物件內容不允許發生改變,只能改變引用指向。

包括:字串、數字、元組

可變型別就是指向的物件內容允許發生改變,可以改變物件內容而引用不變。

包括:列表、字典

注意

1、字典中的key值只能是不可變內容

2、對於不可變型別的全域性變數來說,因其指向的物件不能修改,所以不使用global時無法修改全域性變數。

3、對於可變型別的全域性變數來說,因其指向的物件可以修改,所以不使用global時也可修改全域性變數。

4、Python中函式引數是引用傳遞(注意不是值傳遞)。對於不可變型別,因變數不能修改,所以運算不會影響到變數自身;而對於可變型別來說,函式體中的運算有可能會更改傳入的引數變數。