天天看點

python中的直接指派和深淺拷貝解析

直接指派

在Python中直接指派其實隻是将引用位址之間的傳遞。

python中的直接指派和深淺拷貝解析

如圖所示,這是python中原子類型的指派結果,當你修改變量1的時候,變量2的值并不會随着改變。接下來看一下容器類型[list, dict, set…]的指派情況,我以清單類型舉例:

python中的直接指派和深淺拷貝解析

為什麼修改了list1之後,list2的内容也會改變?

首先他和原子類型的差別在于原子類型是不可變的,是以你隻能通過改變引用對象,指向的記憶體位址也就相應改變了,而清單本身是可變的,是以你可以直接對其進行修改,但是你的修改并不會改變這個清單的記憶體位址,隻不過是可能修改了内部元素的所指向的記憶體位址,而清單本身會對其内部的元素進行一個維護。

python中的直接指派和深淺拷貝解析

淺拷貝

那麼如果我們想要一份同樣的資料,但是是不同的對象該怎麼辦?可以調用對象的copy()方法或者導入copy子產品,調用copy.copy()來生成原對象的一份淺拷貝。

python中的直接指派和深淺拷貝解析

根據截圖看到如果對清單進行元素的添加是支援的,但是子元素的記憶體位址是固定的,是以推測對于原子類型修改沒問題,但是對于容器類型的修改也會出現牽一發而動全身的問題。

python中的直接指派和深淺拷貝解析

根據截圖來看,确實符合之前的推斷隻要他記得是容器的位址,那麼就會出現互相影響,如果想要徹徹底底沒有關系,那麼就需要用到了深拷貝。

深拷貝

深拷貝,調用的copy子產品的deepcopy()方法,可以将目前的對象完全拷貝一份,如圖所示。

python中的直接指派和深淺拷貝解析

首先根據示例來看,深拷貝确實重新建立了一個對象,這點和淺拷貝剛開始是一樣的。

python中的直接指派和深淺拷貝解析

可以看出來原子類型的位址是不變的,但是容器類型的位址是變化的,那麼是不是因為這些原子類型的數值小,是以記憶體位址是固定的,換一個大點的數值做實驗。

python中的直接指派和深淺拷貝解析

可以看出來原子類型的值确實隻是引用的之前的位址,但是對于容器類型的值,确實建立了新的對象,那麼對于子元素的子元素适應嗎?

python中的直接指派和深淺拷貝解析

根據截圖來看,深拷貝會将所有的容器類型全都重新生成一個對象來引用,對于所有的原子類型會沿用之前的位址。