1. 程式人生 > >python可變類型和不可變類型

python可變類型和不可變類型

www 一點 觸發 一份 ble 地址 圖片 log tab

原文地址:http://www.cnblogs.com/huamingao/p/5809936.html

可變類型 Vs 不可變類型

可變類型(mutable):列表,字典

不可變類型(unmutable):數字,字符串,元組

這裏的可變不可變,是指內存中的那塊內容(value)是否可以被改變

代碼:

name1=wupeiqi
name2=name1
print("name1:%s\nname2:%s" %(name1,name2))
name1=alex
print("I have assigned new value to name1.Let‘s see what happens to name2!
") print("name1:%s\nname2:%s" %(name1,name2))

執行結果:

name1:wupeiqi
name2:wupeiqi
I have renamed name1 to new_name.Lets see what happens!
name1:alex
name2:wupeiqi

疑問:為什麽name2的值沒有和name1一起變為alex?下面開始解答,先看圖,後解釋。

以下引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html

變量的賦值

#!/usr/bin/env python
# -*- coding: utf-8 -*-
name1 = "wupeiqi" name2 = "alex"

技術分享圖片

#!/usr/bin/env python
# -*- coding: utf-8 -*-

name1 = "wupeiqi"   
name2 = name1     # 使name2和name1指向同一個對象 賦值,只是創建一個變量,該變量指向原來內存地址,

技術分享圖片

以上引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html

1.引用計數的增減

當對象wupeiqi(圖中藍色的內存區塊wupeiqi)被初次創建並(將其引用)賦值給變量name1時,對象wupeiqi的引用計數被設置為1。

當對象alex(圖中藍色的內存區塊alex)被初次創建並(將其引用)賦值給變量name2時,對象alex的引用計數被設置為1。

當變量name1賦值給變量name2(name2=name1),實際是把對象wupeiqi賦值給name2,因此對象wupeiqi的引用計數自動加1,而對象alex的引用計數自動減1,即減為0,觸發垃圾回收機制。

2. 可變類型 Vs 不可變類型

可變類型(mutable):列表,字典

不可變類型(unmutable):數字,字符串,元組

這裏的可變不可變,是指內存中的那塊內容(value)是否可以被改變。如果是不可變類型,在對對象本身操作的時候,必須在內存中新申請一塊區域(因為老區域#不可變#)。如果是可變類型,對對象操作的時候,不需要再在其他地方申請內存,只需要在此對象後面連續申請(+/-)即可,也就是它的address會保持不變,但區域會變長或者變短。

可以使用內建函數id()來確認對象的身份在兩次賦值前後是否發生了變化。示例可參看http://blog.chinaunix.net/uid-26249349-id-3080279.html

*不可變類型有什麽好處?如果數據是不可變類型,當我們把數據傳給一個不了解的API時,可以確保我們的數據不會被修改。如果我們要操作一個從函數返回的元組,可以通過內建函數list()把它轉換成一個列表。(當被問到列表和元組的區別時,可以說這一點!)

3. 深拷貝 Vs 淺拷貝

copy.copy() 淺拷貝

copy.deepcopy() 深拷貝

淺拷貝是新創建了一個跟原對象一樣的類型,但是其內容是對原對象元素的引用。這個拷貝的對象本身是新的,但內容不是。拷貝序列類型對象(列表\元組)時,默認是淺拷貝。

以下引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html

賦值,只是創建一個變量,該變量指向原來內存地址,如下例:

n4 = n3 = n2 = n1 = "123/‘Wu‘"

技術分享圖片

關於賦值,再看一個字典的例子:

n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n2 = n1

技術分享圖片

淺拷貝,在內存中只額外創建第一層數據,如下圖

import copy
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n3 = copy.copy(n1)

技術分享圖片

深拷貝,在內存中將所有的數據重新創建一份(排除最後一層,即:python內部對字符串和數字的優化),如下圖:

import copy
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n4 = copy.deepcopy(n1)

技術分享圖片

python可變類型和不可變類型