拷貝Python對(duì)象

賦值

Python中對(duì)象的賦值是簡(jiǎn)單的對(duì)象引用(可以把這個(gè)對(duì)象看成一個(gè)盒子,賦值是給這個(gè)盒子上貼不同的標(biāo)簽,指向的都是這個(gè)盒子對(duì)象)

a = 'haha'
b = a
id(a)  # output: 140640656233712
id(b)  # output: 140640656233712

拷貝

淺拷貝

Python中序列類(lèi)型的拷貝默認(rèn)為淺拷貝,可以使用以下幾種方式進(jìn)行拷貝:

  • 完全的切片操作[:]
  • 利用工廠(chǎng)函數(shù),list(),dict()等
  • 使用copy模塊的copy函數(shù)
person = ['name', ['savings', 100.00]]
hubby = person[:]  # 切片拷貝
wifey = list(person)  # 利用工廠(chǎng)函數(shù)拷貝
[id(x) for x in (person, hubby, wifey)]
output: [140640651046408, 140640651435848, 140640650741832]  #可以看到拷貝了2個(gè)新的對(duì)象
# 這3個(gè)對(duì)象id不一致,但是他們的元素id值一樣
[id(x) for x in person]
output: [140640753298320, 140640654842952]
[id(x) for x in hubby]
output: [140640753298320, 140640654842952]
[id(x) for x in wifey]
output: [140640753298320, 140640654842952]
hubby[0] = 'jay'
wifey[0] = 'lucy'
hubby, wifey
output: ['jay', ['savings', 100.00]], ['lucy', ['savings', 100.00]]
hubby[1][1] = 50.00
hubby, wifey
output: ['jay', ['savings', 50.00]], ['lucy', ['savings', 50.00]] 

通過(guò)上面的例子可以看到,通過(guò)改變hubby[1][1]的值,wifey[1][1]的值也被改變了,這是因?yàn)閷?duì)一個(gè)對(duì)象進(jìn)行淺拷貝其實(shí)是新創(chuàng)建了一個(gè)類(lèi)型和原對(duì)象一樣,內(nèi)容為原對(duì)象的引用。
person這個(gè)對(duì)象有2個(gè)元素,不可變對(duì)象字符串和可變對(duì)象列表,當(dāng)hubby[0] = 'jay'時(shí),由于字符串是不可變對(duì)象,相當(dāng)于新創(chuàng)建了一個(gè)對(duì)象‘jay’,賦值給了hubby[1],wifey[0] = 'lucy',也是新創(chuàng)建一個(gè)'lucy'對(duì)象賦值給了wifey。hubby[1][1]=50.00時(shí),因?yàn)閔ubby[1]為一個(gè)列表可變對(duì)象,所以原地更改了這個(gè)列表對(duì)象的值,id并沒(méi)有改變,所以對(duì)應(yīng)的person[1],wifey[1]中的值也發(fā)生了改變

深拷貝

對(duì)容器元素中的原有的非原子對(duì)象進(jìn)行全新的拷貝(id值不一樣),使用copy模塊的deepcopy函數(shù)進(jìn)行深拷貝

person = ['name', ['savings', 100.00]]
hubby = person  # 賦值操作
import copy
wifey = copy.deepcopy(person)
[id(x) for x in (person, hubby, wifey)]
output: [140640651021896, 140640651021896, 140640651420744]
[id(x) for x in person]
output: [140640753298320, 140640654842952]
[id(x) for x in hubby]
output: [140640753298320, 140640654842952]  # 因?yàn)樯厦孀龅氖琴x值操作所以id同person一致
[id(x) for x in wifey]
output: [140640753298320, 140640652252360]  # 字符串的id同person[0]一致,列表的id同person[1]的不一致,所以只對(duì)深拷貝只對(duì)非原子對(duì)象進(jìn)行了全新的拷貝
hubby[0] = 'jay'
wifey[0] = 'lucy'
hubby[1][1] = 50.00
hubby, wifey
output: ['jay', ['savings', 50.00]], ['lucy', ['savings', 100.00]]
  • 非容器類(lèi)型(比如數(shù)字、字符串這類(lèi)原子類(lèi)型的對(duì)象)沒(méi)有拷貝這一說(shuō),淺拷貝是用完全切片操作來(lái)完成的
  • 如果元祖變量只包含原子類(lèi)型的對(duì)象,對(duì)它進(jìn)行深拷貝將不會(huì)進(jìn)行

原子類(lèi)型:
Python中以存儲(chǔ)模型來(lái)對(duì)對(duì)象進(jìn)行劃分,分為原子類(lèi)型和容器類(lèi)型,即看這種類(lèi)型的對(duì)象能保存多少個(gè)對(duì)象。一個(gè)能保存單個(gè)對(duì)象的類(lèi)型我們稱(chēng)為原子類(lèi)型或標(biāo)量存儲(chǔ)類(lèi)型,可容納多個(gè)對(duì)象的類(lèi)型我們稱(chēng)為容器類(lèi)型。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容