python 淺copy和深copy

原文請看:https://www.jianshu.com/p/a8f1af357046

概述

本文涉及到主要的概念有:

變量(名)
引用
對象
可變對象和不可變對象
拷貝
深拷貝和拷貝

正文

像Java,Python這樣的語言,存在着深拷貝,淺拷貝的問題。下面我們先通過一張圖來看看變量和對象的關係:

在這裏插入圖片描述

對象和變量

我們要明確以下概念:

變量 是系統變量名錶中的元素(可以想象成人的名字)
對象 是計算機分配的一塊內存,需要足夠的空間去表示它的值(可以想象成真正的人)
引用 是 自動形成的從變量到對象的 指針(給人對象取人名變量名)
如果不清楚動態類型變量的概念,可以看一下下面的總結:

Python的變量創建過程是在代碼第一次給他賦值就創建了變量,之後的賦值 會改變已經創建的變量名的值
Python的變量是沒有類型的,變量是通用的,只是在一個特定的時間點,引用了一個特定的對象
Python中 使用變量的時候,當變量出現在表達式中時,它會馬上被所引用的對象所替代。當然,使用沒賦值的變量會產生錯誤
在Python中,對象按照可變不可變分爲可變對象和不可變對象:
可變對象 指 可以在原處修改,而不用創建新的對象(包括列表,字典,集合);
不可變對象指 不支持在原處修改,只能通過表達式創建新的對象,然後把結果分配給變量(包括 數字,字符串,元組)。

像a = 3,這段代碼的執行過程是這樣:

創建一個對象表示3
創建一個變量a, 如果它還沒有創建的話
將變量與新的對象連接
因爲這樣的特性,如果兩個對象同時指向一個可變對象,可能會有不期望的結果:

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

In [2]: b = a

In [3]: a[0] = 0

In [4]: a
Out[4]: [0, 2, 3, 4]

In [5]: b
Out[5]: [0, 2, 3, 4]

拷貝:

在業務中有時我們需要複製一個對象,但是又不想對原對象產生副作用,那就不能通過賦值給新變量來解決了(賦值不是拷貝一個對象)。Python專門提供了一種拷貝機制,基於原對象創建一個含有相同值的對象。拷貝有copy模塊提供。

拷貝分成淺拷貝和深拷貝。

淺拷貝包括:

對列表切片拷貝L[:]
調用對象的拷貝方法:list.copy()
調用copy.copy()
深拷貝包括:

調用copy.deepcopy()
那麼,淺拷貝和深拷貝有什麼異同呢?兩種拷貝的異同可以用下表描述:

兩種拷貝的異同
來看一段代碼體會一下:

In [6]: x = [1, 2]
In [7]: y = [3, 4]
In [8]: z = [x, y]
In [10]: a = copy.copy(z)

In [12]: a[0] is z[0]
Out[12]: True

In [13]: b = copy.deepcopy(z)

In [14]: b[0] is z[0]
Out[14]: False

解釋:

淺拷貝拷貝出來的a對象是引用x和y,當修改x或y的值時,a也會改變;
深拷貝會把裏面的元素也重新拷貝一份,拷貝了一份x和y的值相等的兩個元素,修改x和y的值,不會對b產生影響。

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