一、問題引出淺拷貝
首先看下面代碼的執行情況:
a = [1, 2, 3]print('a = %s' % a) # a = [1, 2, 3]b = aprint('b = %s' % b) # b = [1, 2, 3]a.append(4) # 對a進行修改print('a = %s' % a) # a = [1, 2, 3, 4]print('b = %s' % b) # b = [1, 2, 3, 4]b.append(5) # 對b進行修改print('a = %s' % a) # a = [1, 2, 3, 4, 5]print('b = %s' % b) # b = [1, 2, 3, 4, 5]上面的代碼比較簡單,定義了一個變量a,它是一個數值[1, 2, 3]的列表,通過一個簡單的賦值語句 b = a 定義變量b,它同樣也是數值[1, 2, 3]的列表。
問題是:如果此時修改變量a,對b會有影響嗎?同樣如果修改變量b,對a又會有影響嗎?
從代碼運行結果可以看出,無論是修改b還是修改a(注意這種修改的方式,是用append,直接修改原列表,而不是重新賦值),都另一方都是有影響的。
當然這個原因其實很好理解,變量a指向的是列表[1, 2, 3]的地址值,當用 = 進行賦值運算時,b的值也相應的指向的列表[1, 2, 3]的地址值。在python中,可以通過id(變量)的方法來查看地址值,我們來查看下a,b變量的地址值,看是不是相等:
# 注意,不同機器上,這個值不同,但只要a,b兩個變量的地址值是一樣的就能說明問題了print(id(a)) # 4439402312print(id(b)) # 4439402312
所以原理如下圖所示:

因此,只要是在地址值:4439402312上的列表進行修改的話,a,b都會發生變化。(注意我這里說的修改,是在地址值為:4439402312上的列表進行的修改,而不說對變量a進行修改,因為對變量a的修改方式有兩種,本文結尾會解釋為什么不說對變量a進行修改) 。所以我們便引出了以下概念:
對于這種是將引用進行拷貝賦值給另一個變量的方式(即拷貝的是地址值),我們稱之為淺拷貝。
二、如何進行深拷貝
python中實現深拷貝的方式很簡單,只需要引入copy模塊,調用里面的deepcopy()的方法即可,示例代碼如下:
import copya = [1, 2, 3]b = copy.deepcopy(a)print('a = %s' % a) # a = [1, 2, 3]print('b = %s' % b) # b = [1, 2, 3]b.append(4)print('a = %s' % a) # a = [1, 2, 3]print('b = %s' % b) # b = [1, 2, 3, 4]從代碼執行情況來看,我們已經實現了深拷貝。這時我們再來看下兩個變量的地址值:
print(id(a)) # 4321416008print(id(b)) # 4321416200
果然就不一樣了。我們再通過一個圖來看下深拷貝的原理:

三、copy模塊方法簡介
從深拷貝的實現過程,我們知道copy模塊,也使用了里面的deepcopy()方法。下面我們來介紹下copy模塊中的copy()與deepcopy()方法。
首先介紹我們已經使用過的deepcopy()方法,官方文檔介紹如下:
新聞熱點
疑難解答