【python基礎】可變型別與不可變型別
阿新 • • 發佈:2019-01-03
從上面的文章可以總結出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中函式引數是引用傳遞(注意不是值傳遞)。對於不可變型別,因變數不能修改,所以運算不會影響到變數自身;而對於可變型別來說,函式體中的運算有可能會更改傳入的引數變數。