深拷貝和淺拷貝

2022-01-14 17:11:32 字數 2114 閱讀 9737

一)2個為什麼

先通過2個為什麼來了解一下python記憶體中變數的儲存情況。

>>> name = [1,2,3,["alex","rain"]]

>>> name2 = name.copy() # 將原列表copy乙份賦值給name2

>>> print(name)

[1, 2, 3, ['alex', 'rain']]

>>> print(name2)

[1, 2, 3, ['alex', 'rain']]

>>>

name與name2相同

第乙個為什麼:

>>> name[1] = -2

>>> print(name)

[1, -2, 3, ['alex', 'rain']]

>>> print(name2)

[1, 2, 3, ['alex', 'rain']]

>>>

name[1]改變後,name改變了而name2沒有改變,為什麼?

第二個為什麼:

>>> name[3][0] = "alex"

>>> print(name)

[1, -2, 3, ['alex', 'rain']]

>>> print(name2)

[1, 2, 3, ['alex', 'rain']]

>>>

將name[3][0]的值改後,name改變了,name2也改變了,為什麼?

第乙個為什麼和第二個為什麼都對列表進行了更改,而結果為什麼不一樣尼?

首先我們要清楚,列表name的元素是存在於多塊記憶體空間中的,不是在同一塊;每個元素的記憶體位址都是獨立的。

變數name等於[1,2,3,["alex","rain"]]這個含有這些元素的列表的時候,記憶體中發生了2件事:一是變數name是個列表,開闢了一塊記憶體空間;二是列表裡的每乙個元素各自開闢了屬於自己的記憶體空間。name列表開闢的記憶體空間裡存的不是元素,而是每個元素的記憶體位址。每乙個元素比作是家的話,name列表的記憶體空間裡存的就是郵寄到你家的包裹上的位址,是乙個指向。

name2 copy name,只是copy了name中的元素(一級元素)的記憶體位址,即將id(1),id(2),id(3)等這些元素的記憶體位址複製到了name2的記憶體空間裡了。

解答第乙個為什麼:

將name中的2改為-2,name內的2的記憶體位址會被擦除,然後將新開闢的-2的記憶體位址佔位到此處。由於2的記憶體位址還被name2引用,所以2的記憶體不會被釋放,依然存在。

對於第乙個為什麼,name的第乙個元素為-2,name2的第乙個元素為2,因為這2個的記憶體位址不同,所以位址所指向的資料(在記憶體裡以十六進製制數表示)就不同。記憶體位址不同,資料不同。

解答第二個為什麼:

要區分清楚列表的記憶體位址和列表中元素的記憶體位址是不一樣的,不要混淆

name2 copy name的時候,copy了每個元素(一級元素)的記憶體位址。name中元素['alex', 'rain']這個小列表的記憶體位址也被複製,即name中的小列表的記憶體位址與name2中的小列表的記憶體位址是一樣的,也就是說name2中的小列表沒有開闢新的空間,而是引用了name中小列表的空間。id(name[3]) = id(name2[3]).

第二個為什麼中,對name內的小列表中的元素"alex"進行了全大寫更改(過程:"alex"開闢了一塊新的空間,將這塊新空間的位址放到小列表中的索引為0的位置),即小列表(巢狀列表)內的元素的發生改變,而小列表的記憶體位址沒有發生變化,name2中的小列表的記憶體位址與name中的小列表的記憶體位址一樣,所以name中小列表的值發生變化,name2中的小列表的值也會變化。記憶體位址相同,指向的資料也相同

.深拷貝:copy 模組的 deepcopy 方法,完全拷貝了父物件及其子物件。即name2不僅拷貝了name中一級元素(1,2,3,["alex","rain"])的的記憶體位址,也拷貝了巢狀列表,["alex","rain"]裡面的"alex"和"rain"的記憶體位址。

深拷貝和淺拷貝

淺拷貝就是物件的資料成員之間的簡單賦值,如你設計了乙個沒有類而沒有提供它的複製建構函式,當用該類的乙個物件去給令乙個物件賦值時所執行的過程就是淺拷貝,如 class a a private int data int main 這一句b a 就是淺拷貝,執行完這句後b.data 5 如果物件中沒有其他...

淺拷貝和深拷貝

以下情況都會呼叫拷貝建構函式 乙個物件以值傳遞的方式傳入函式體 例如 已知class a,class b void func a a void func a a func b b 此時函式對b的操作是呼叫拷貝建構函式後的臨時拷貝物件。多數傳指標 乙個物件以值傳遞的方式從函式返回 如 return b...

深拷貝和淺拷貝

ios提供了copy和mutablecopy方法,顧名思義,copy就是複製了乙個imutable的物件,而mutablecopy就是複製了乙個mutable的物件。以下將舉幾個例子來說明。1 系統的非容器類物件 這裡指的是nsstring nsnumber等等一類的物件。nsstring stri...