亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python對(duì)象的深拷貝和淺拷貝詳解

 更新時(shí)間:2014年08月25日 08:44:45   投稿:junjie  
這篇文章主要介紹了Python對(duì)象的深拷貝和淺拷貝詳解,本文從Python核心編程2書(shū)中摘錄而來(lái),總結(jié)的比較精辟,需要的朋友可以參考下

本文內(nèi)容是在《Python核心編程2》上看到的,感覺(jué)很有用便寫(xiě)出來(lái),給大家參考參考!

淺拷貝

首先我們使用兩種方式來(lái)拷貝對(duì)象,一種是切片,另外一種是工廠方法。然后使用id函數(shù)來(lái)看看它們的標(biāo)示符

復(fù)制代碼 代碼如下:

# encoding=UTF-8
 
obj = ['name',['age',18]]
a=obj[:]
b=list(obj)
for x in obj,a,b:
    print id(x)
 
35217032
35227912
29943304

 
他們的id都不同,按照正常的判斷,三個(gè)不同id的對(duì)象應(yīng)該都是獨(dú)立的。那么我們先給他們改改名看看
復(fù)制代碼 代碼如下:

# encoding=UTF-8
 
obj = ['name',['age',18]]
a=obj[:]
b=list(obj)
for x in obj,a,b:
    print id(x)
    
a[0] = 'lisi'
b[0] = 'zhangsan'
 
print a
print b
 
35217032
35227912
33547784
['lisi', ['age', 18]]
['zhangsan', ['age', 18]]

對(duì)象a與b分別賦予了不同的名字,下來(lái)我們來(lái)看看給a對(duì)象改一個(gè)年齡
復(fù)制代碼 代碼如下:

# encoding=UTF-8
 
obj = ['name',['age',18]]
a=obj[:]
b=list(obj)
for x in obj,a,b:
    print id(x)
    
a[0] = 'lisi'
b[0] = 'zhangsan'
 
print a
print b
 
a[1][1] = 25
 
print a
print b
 
35217032
35227912
29943304
['lisi', ['age', 18]]
['zhangsan', ['age', 18]]
['lisi', ['age', 25]]
['zhangsan', ['age', 25]]

細(xì)心的朋友應(yīng)該看出來(lái)了,改變a[0]元素與b[0]元素都互不影響,為何改變a[1][1]的元素會(huì)影響b[1][1]的元素呢?
要解開(kāi)這個(gè)問(wèn)題,只有先了解深拷貝與淺拷貝。以上實(shí)例中,我們創(chuàng)建的a與b都是從obj對(duì)象的淺拷貝,obj中第一個(gè)元素是字符串屬于不可變類(lèi)型,第二個(gè)元素是列表屬于可變類(lèi)型。因此我們進(jìn)行拷貝對(duì)象時(shí),字符串被顯示拷貝重新創(chuàng)建了一個(gè)字符串,而列表只是復(fù)制引用,所以改變列表的元素會(huì)影響所有引用對(duì)象。從下列的id值中,你就能看明白了
復(fù)制代碼 代碼如下:

# encoding=UTF-8
 
obj = ['name',['age',18]]
a=obj[:]
b=list(obj)
 
for x in obj,a,b:
    print id(x[0]),id(x[1])
print
 
a[0] = 'lisi'
b[0] = 'zhangsan'
 
for x in obj,a,b:
    print id(x[0]),id(x[1])
print
 
a[1][1] = 25
b[1][1] = 30
 
for x in obj,a,b:
    print id(x[0]),id(x[1])
print
 
32564088 34496008
32564088 34496008
32564088 34496008
 
32564088 34496008
34574704 34496008
33970672 34496008
 
32564088 34496008
34574704 34496008
33970672 34496008

復(fù)制對(duì)象的時(shí)候,我們可以看到所有元素的id都一直,我們分別改變了a與b對(duì)象的第一個(gè)字符串元素,因?yàn)樽址遣豢勺儗?duì)象,所以改變后等于新創(chuàng)建,于是a與b的第一個(gè)字符串元素id不一致。而a與b的第二個(gè)元素都是列表可變對(duì)象,所以無(wú)論修改任何一個(gè)id值都表示一個(gè)指針,始終影響其它引用對(duì)象的值。
因此也就為什么修改a對(duì)象的年齡會(huì)影響b對(duì)象的年齡值,或者修改b對(duì)象的年齡值也會(huì)影響a對(duì)象的年齡值,包括obj對(duì)象在內(nèi)。

深拷貝

以上都是淺拷貝,那么我們希望拷貝的對(duì)象是獨(dú)立的,修改時(shí)不要影響其它值,這種我們稱(chēng)為深拷貝。實(shí)現(xiàn)深拷貝我們需要引用一個(gè)copy模塊,copy模塊有兩個(gè)函數(shù)可用,一個(gè)是copy淺拷貝;另一個(gè)是deepcopy深拷貝。

復(fù)制代碼 代碼如下:

# encoding=UTF-8
import copy
obj = ['name',['age',18]]
a=copy.deepcopy(obj)
b=copy.deepcopy(obj)
 
for x in a,b:
    print id(x[0]),id(x[1])
print
 
a[1][1] = 25
b[1][1] = 30
 
print a
print b
 
33612664 35477256
33612664 35477640
 
['name', ['age', 25]]
['name', ['age', 30]]

使用深拷貝后,列表元素的id不一致,表示獨(dú)立對(duì)象,修改任何一個(gè)列表元素的值都不會(huì)影響其它對(duì)象。

以下是幾點(diǎn)拷貝操作的注意事項(xiàng):
第一、非容器類(lèi)型(比如數(shù)字、字符串和其它“院子”類(lèi)型的對(duì)象,像代碼、類(lèi)型和range對(duì)象等)沒(méi)有被拷貝一說(shuō),淺拷貝是用完全切片操作來(lái)完成。

第二、如果元祖變量只包含原子類(lèi)型對(duì)象,對(duì)它的深拷貝將不會(huì)進(jìn)行。
我們把上面的例子改成元祖,然后使用深拷貝試試

復(fù)制代碼 代碼如下:

# encoding=UTF-8
import copy
obj = ['name',('age',18)]
a=copy.deepcopy(obj)
b=copy.deepcopy(obj)
 
for x in a,b:
    print id(x),id(x[1])
print
 
34703752 34693000
34756616 34693000

相關(guān)文章

最新評(píng)論