當前位置:成語大全網 - 新華字典 - Python中的深拷貝和淺拷貝

Python中的深拷貝和淺拷貝

這篇文章主要介紹了Python中的深拷貝和淺拷貝詳解,本文講解了變量-對象-引用、可變對象-不可變對象、拷貝等內容,需要的朋友可以參考下

要說清楚Python中的深淺拷貝,需要搞清楚下面壹系列概念:

變量-引用-對象(可變對象,不可變對象)-切片-拷貝(淺拷貝,深拷貝)

變量-對象-引用

在Python中壹切都是對象,比如說:3, 3.14, Hello, [1,2,3,4],{a:1}......

甚至連type其本身都是對象,type對象

Python中變量與C/C++/Java中不同,它是指對象的引用,Python是動態類型,程序運行時候,會根據對象的類型

來確認變量到底是什麽類型。

單獨賦值: 比如說:

復制代碼 代碼如下:

a = 3

在運行a=3後,變量a變成了對象3的壹個引用。在內部,變量事實上是到對象內存空間的壹個指針

因為Python的變量不過是對象的引用,或指向對象的指針,因此在程序中可以經常改變變量引用

復制代碼 代碼如下:

x = 42 #變量綁定到整型對象

x = Hello #現在又成了字符串

x = [1,2,3] #現在又成了列表

專業表述如下:

變量是壹個系統表的元素,擁有指向對象的連接的空間

對象是被分配的壹塊內存,存儲其所代表的值

引用是自動形成的從變量到對象的指針

特別註意: 類型屬於對象,不是變量

比如像剛才的a=3, 整數對象3包含了兩重信息

1.值為3

2.壹個頭部信息:告訴Pthyon,這是個整數對象[相當於壹個指向int的指針]

***享引用: 比如說:

復制代碼 代碼如下:

a = 3

b = a

在運行賦值語句b = a之後,變量a和變量b指向了同壹個對象的內存空間.

從上圖可以看到,a和b,其id完全壹樣,指向同壹個整數對象3,或者說同壹塊內存

如果刪掉a後, 不會影響b

拷貝概念的引入就是針對:可變對象的***享引用潛在的副作用而提出的.

可變對象-不可變對象

在Python中不可變對象指:壹旦創建就不可修改的對象,包括字符串,元祖,數字

在Python中可變對象是指:可以修改的對象,包括:列表、字典

上面說的a,b都是整數,整數是不可變對象,如果是可變對象的話,就是另外壹回事了。

復制代碼 代碼如下:

L1 = [2,3,4] #L1變量指向的是壹個可變對象:列表

L2 = L1 #將L1值賦給L2後,兩者***享引用同壹個列表對象[1,2,3,4]

L1[0] = 200 #因為列表可變,改變L1中第壹個元素的值

L1; L2 #改變後,L1,L2同時改變,因為對象本身值變了

[200, 3, 4]

[200, 3, 4]

如果不想改變列表L2的值,有兩種方法:切片 和 copy模塊

復制代碼 代碼如下:

L1 = [2,3,4]

L2 = L1

id(L1);id(L2) #***享引用壹個可變對象

45811784L

45811784L

L2 = L1[:] #切片操作

id(L1);id(L2) #切片後,對象就不壹樣了

45811784L

45806920L

L1[0] = 200

L1;L2 #L1發生改變,L2沒有變化

[200, 3, 4]

[2, 3, 4]

拷貝

1. 切片技術應用於所有的序列,包括:列表、字符串、元祖

但切片不能應用於字典。對字典只能使用D.copy()方法或D.deepcopy()方法.

2. 深淺拷貝,即可用於序列,也可用於字典

復制代碼 代碼如下:

import copy

X = copy.copy(Y) #淺拷貝:只拷貝頂級的對象,或者說:父級對象

X = copy.deepcopy(Y) #深拷貝:拷貝所有對象,頂級對象及其嵌套對象。或者說:父級對象及其子對象

如果字典只有頂級對象:

如果字典中嵌套對象:

結論

深淺拷貝都是對源對象的復制,占用不同的內存空間

如果源對象只有壹級目錄的話,源做任何改動,不影響深淺拷貝對象

如果源對象不止壹級目錄的話,源做任何改動,都要影響淺拷貝,但不影響深拷貝

序列對象的切片其實是淺拷貝,即只拷貝頂級的對象