Python —— 深拷貝和淺拷貝

1、淺拷貝

淺拷貝就是對一個對象父級(外層)的拷貝,並不會拷貝子級(內部)。簡單舉個例子:

import copy

a = [1, 2, 3]
b = [3, 4, 5]
c = [a, b]
d = copy.copy(c)

上面代碼中,c是對象父級,a和b是對象子級。當使用淺拷貝copy.copy()時,只會對c進行拷貝,不會對a和b進行拷貝。

具體可以進行驗證:

import copy

a = [1, 2, 3]
b = [3, 4, 5]
c = [a, b]
d = copy.copy(c)

print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))

通過上面的代碼可以發現,c和d的內存地址是不一樣的,而子級的內存地址是一樣的。

因此可以簡單理解,當一個對象有對象父級和對象子級時,淺拷貝只會對對象父級進行拷貝而不會對對象子級進行拷貝。

但是當對象不分父級和子級的時候,淺拷貝就是簡單的對對象進行拷貝:

import copy

a = [1, 2, 3]
b = copy.copy(a)

print(id(a))
print(id(b))

這種情況下a和b的內存地址是不一樣的。

還需要注意的一種情況是,當對象父級的數據類型爲不可變類型,比如是元組時,淺拷貝對象的時候還是引用原對象的地址。

import copy

a = [1, 2, 3]
b = [3, 4, 5]
c = (a, b)
d = copy.copy(c)

print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))

在上面這種情況下,對象父級是一個不可變數據類型,元組。因此在使用淺拷貝的時候,是對原對象的直接引用。因爲父級對象是不可變類型,因此如果要修改父級的數據,會重新開闢新的內存空間進行存放,因此淺拷貝引用原對象的地址是沒有問題的。

2、深拷貝

深拷貝是對一個對象的所有層次的拷貝,內部和外部都會被拷貝。

簡單舉個例子:

import copy

a = [1, 2, 3]
b = [2, 3, 4]
c = [a, b]
d = copy.deepcopy(c)

print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))

代碼中copy.deepcopy()是對原對象進行深拷貝,這種情況下,對象父級被拷貝,對象子級也會被拷貝,對象之間的內存地址完全不同。

但是深拷貝中需要注意,當對象父級是一個不可變類型,對象子級是一個不可變類型,當使用深拷貝的時候,新對象是對原對象的引用。

import copy

a = (1, 2, 3)
b = (2, 3, 4)
c = (a, b)
d = copy.deepcopy(c)

print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))

代碼中的對象父級和子級都是不可變類型,元組。這種情況下,深拷貝得到的新對象是對原對象的引用,兩者對應的內存地址是一樣的。

深拷貝的作用是在做數據清洗或者數據修改等操作前,對原始數據複製一份,以防數據修改,找不到原數據。

當對象父級和對象子級是不可變類型時,是不能在原始對象上對數據進行修改的,這時候深拷貝對對象的拷貝是引用就可以理解了。因爲我是不可變數據,所以怎麼對數據進行清洗也不會改變原始數據,所以直接對原對象進行引用就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章