python深淺拷貝的深度解析 記憶體 位址

2022-07-11 08:15:11 字數 1477 閱讀 9865

前置知識

1.python沒有指標, 可以通過內建函式id來檢視記憶體位址

2.python中list存放的是位址, 而非元素本身, 位址是按順序存放的

3.python容器型別list有兩種位址, 乙個是外層物件/父物件位址, 乙個是每個元素/子物件的位址

4.當修改list中的不可變物件時, 物件會發生拷貝copy-on-write, list存放的位址會發生變化, 這點可以保證任何拷貝都無需拷貝不可變物件本身, 只需要拷貝位址即可

import copy

a = [1, 2, [3, 4]]

b = a

c = a.copy()

d = copy.deepcopy(a)

# 測試

assert id(a) == id(b) and id(a[0]) == id(b[0]) and id(a[2]) == id(b[2])

assert id(a) != id(c) and id(a[0]) == id(c[0]) and id(a[2]) == id(c[2])

assert id(a) != id(d) and id(a[0]) == id(d[0]) and id(a[2]) != id(d[2])

a[0] = 5

assert id(a) == id(b) and id(a[0]) == id(b[0]) and id(a[2]) == id(b[2])

assert id(a) != id(c) and id(a[0]) != id(c[0]) and id(a[2]) == id(c[2])

assert id(a) != id(d) and id(a[0]) != id(d[0]) and id(a[2]) != id(d[2])

assert id(a) == id(b) and id(a[0]) == id(b[0]) and id(a[2]) == id(b[2])

assert id(a) != id(c) and id(a[0]) != id(c[0]) and id(a[2]) == id(c[2])

assert id(a) != id(d) and id(a[0]) != id(d[0]) and id(a[2]) != id(d[2])

這三種"拷貝"方式有各自的含義

1.b = a

b是a的乙個引用, 不存在任何物件和位址拷貝, 即b只是a的乙個別名

2.c = a.copy()

c拷貝了a的外層物件, 內層物件的位址

當a中的不可變物件發生變化, a中的位址變化(參照前置知識4), c中的位址不變, 體現為c中的元素不跟隨a變化

當a中的可變物件發生變化, a中的位址不變, c中的位址不變, 體現為c中的元素跟隨a變化

3.d = copy.deepcopy(a)

d拷貝了a的外層物件, 內層可變物件, 內層不可變物件的位址(參照前置知識4), 與a完全獨立,

如有疏忽錯誤,

歡迎批評指正!

《深 淺拷貝解析(C )》

問題 在c 中如果沒有顯式定義拷貝建構函式,編譯系統會生成預設的拷貝建構函式,這種機制方便程式設計師編寫程式的同時也為程式設計師帶來了一些麻煩。當類中含有指標成員變數時,預設的拷貝建構函式會將拷貝函式的指標變數值賦給待拷貝建構函式的指標變數,使兩個指標變數指向同一片空間,物件銷毀時,析構函式就會釋放...

C 解析深淺拷貝

首先我們看看淺拷貝。淺拷貝就是將物件中的所有字段複製到新物件中去,淺拷貝對於值型別和引用型別有不同的影響。值型別的值被複製到副本中後,修改副本中的值不會影響原來物件的值。然而引用型別被複製到副本中的是引用型別的引用。不是引用的物件。這樣再修改副本中的值是會導致原來物件的值也被修改了。但是這裡引用型別...

python 深淺拷貝案例 python 深淺拷貝

深淺拷貝 對於 數字 和 字串 而言,賦值 淺拷貝和深拷貝無意義,因為其永遠指向同乙個記憶體位址 import copy a1 22255 a2 22255 print id a1 id a2 3428240 3428240 對於字典 元祖 列表 而言,進行賦值 淺拷貝和深拷貝時,其記憶體位址的變化...