Python中的深拷貝和淺拷貝詳解
要說(shuō)清楚Python中的深淺拷貝,需要搞清楚下面一系列概念:
變量-引用-對(duì)象(可變對(duì)象,不可變對(duì)象)-切片-拷貝(淺拷貝,深拷貝)
【變量-對(duì)象-引用】
在Python中一切都是對(duì)象,比如說(shuō):3, 3.14, 'Hello', [1,2,3,4],{'a':1}......
甚至連type其本身都是對(duì)象,type對(duì)象
Python中變量與C/C++/Java中不同,它是指對(duì)象的引用,Python是動(dòng)態(tài)類(lèi)型,程序運(yùn)行時(shí)候,會(huì)根據(jù)對(duì)象的類(lèi)型
來(lái)確認(rèn)變量到底是什么類(lèi)型。
單獨(dú)賦值: 比如說(shuō):
>>> a = 3
在運(yùn)行a=3后,變量a變成了對(duì)象3的一個(gè)引用。在內(nèi)部,變量事實(shí)上是到對(duì)象內(nèi)存空間的一個(gè)指針
因?yàn)镻ython的變量不過(guò)是對(duì)象的引用,或指向?qū)ο蟮闹羔槪虼嗽诔绦蛑锌梢越?jīng)常改變變量引用
>>> x = 42 #變量綁定到整型對(duì)象
>>> x = 'Hello' #現(xiàn)在又成了字符串
>>> x = [1,2,3] #現(xiàn)在又成了列表
專(zhuān)業(yè)表述如下:
變量是一個(gè)系統(tǒng)表的元素,擁有指向?qū)ο蟮倪B接的空間
對(duì)象是被分配的一塊內(nèi)存,存儲(chǔ)其所代表的值
引用是自動(dòng)形成的從變量到對(duì)象的指針
特別注意: 類(lèi)型屬于對(duì)象,不是變量
比如像剛才的a=3, 整數(shù)對(duì)象3包含了兩重信息
1.值為3
2.一個(gè)頭部信息:告訴Pthyon,這是個(gè)整數(shù)對(duì)象[相當(dāng)于一個(gè)指向int的指針]
共享引用: 比如說(shuō):
>>> a = 3
>>> b = a
在運(yùn)行賦值語(yǔ)句b = a之后,變量a和變量b指向了同一個(gè)對(duì)象的內(nèi)存空間.
從上圖可以看到,a和b,其id完全一樣,指向同一個(gè)整數(shù)對(duì)象3,或者說(shuō)同一塊內(nèi)存
如果刪掉a后, 不會(huì)影響b
拷貝概念的引入就是針對(duì):可變對(duì)象的共享引用潛在的副作用而提出的.
【可變對(duì)象-不可變對(duì)象】
在Python中不可變對(duì)象指:一旦創(chuàng)建就不可修改的對(duì)象,包括字符串,元祖,數(shù)字
在Python中可變對(duì)象是指:可以修改的對(duì)象,包括:列表、字典
上面說(shuō)的a,b都是整數(shù),整數(shù)是不可變對(duì)象,如果是可變對(duì)象的話,就是另外一回事了。
>>> L1 = [2,3,4] #L1變量指向的是一個(gè)可變對(duì)象:列表
>>> L2 = L1 #將L1值賦給L2后,兩者共享引用同一個(gè)列表對(duì)象[1,2,3,4]
>>> L1[0] = 200 #因?yàn)榱斜砜勺?,改變L1中第一個(gè)元素的值
>>> L1; L2 #改變后,L1,L2同時(shí)改變,因?yàn)閷?duì)象本身值變了
[200, 3, 4]
[200, 3, 4]
如果不想改變列表L2的值,有兩種方法:切片 和 copy模塊
>>> L1 = [2,3,4]
>>> L2 = L1
>>> id(L1);id(L2) #共享引用一個(gè)可變對(duì)象
45811784L
45811784L
>>> L2 = L1[:] #切片操作
>>> id(L1);id(L2) #切片后,對(duì)象就不一樣了
45811784L
45806920L
>>> L1[0] = 200
>>> L1;L2 #L1發(fā)生改變,L2沒(méi)有變化
[200, 3, 4]
[2, 3, 4]
【拷貝】
1. 切片技術(shù)應(yīng)用于所有的序列,包括:列表、字符串、元祖
>>>但切片不能應(yīng)用于字典。對(duì)字典只能使用D.copy()方法或D.deepcopy()方法.
2. 深淺拷貝,即可用于序列,也可用于字典
>>> import copy
>>> X = copy.copy(Y) #淺拷貝:只拷貝頂級(jí)的對(duì)象,或者說(shuō):父級(jí)對(duì)象
>>> X = copy.deepcopy(Y) #深拷貝:拷貝所有對(duì)象,頂級(jí)對(duì)象及其嵌套對(duì)象?;蛘哒f(shuō):父級(jí)對(duì)象及其子對(duì)象
如果字典只有頂級(jí)對(duì)象:
如果字典中嵌套對(duì)象:
【結(jié)論】
深淺拷貝都是對(duì)源對(duì)象的復(fù)制,占用不同的內(nèi)存空間
如果源對(duì)象只有一級(jí)目錄的話,源做任何改動(dòng),不影響深淺拷貝對(duì)象
如果源對(duì)象不止一級(jí)目錄的話,源做任何改動(dòng),都要影響淺拷貝,但不影響深拷貝
序列對(duì)象的切片其實(shí)是淺拷貝,即只拷貝頂級(jí)的對(duì)象
相關(guān)文章
網(wǎng)紅編程語(yǔ)言Python將納入高考你怎么看?
12月編程語(yǔ)言排行榜出爐,在編程排行榜上,排名第四的是Python。而網(wǎng)絡(luò)上也瘋傳,編程語(yǔ)言Python將納入高考,Python不虧是網(wǎng)紅的編程語(yǔ)言2018-06-06python實(shí)現(xiàn)簡(jiǎn)單的超市商品銷(xiāo)售管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)超市商品銷(xiāo)售管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11windows python3安裝Jupyter Notebooks教程
這篇文章主要介紹了windows python3安裝Jupyter Notebooks教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04PyTorch基礎(chǔ)之torch.nn.CrossEntropyLoss交叉熵?fù)p失
這篇文章主要介紹了PyTorch基礎(chǔ)之torch.nn.CrossEntropyLoss交叉熵?fù)p失講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02詳解python中DRF框架的數(shù)據(jù)校驗(yàn)方式
這篇文章主要為大家詳細(xì)介紹了python中DRF框架的數(shù)據(jù)校驗(yàn)方式,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以跟隨小編一起了解一下2023-10-10Python使用type動(dòng)態(tài)創(chuàng)建類(lèi)操作示例
這篇文章主要介紹了Python使用type動(dòng)態(tài)創(chuàng)建類(lèi)操作,結(jié)合實(shí)例形式詳細(xì)分析了Python使用type動(dòng)態(tài)創(chuàng)建類(lèi)的具體原理、實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下2020-02-02如何利用python實(shí)現(xiàn)列表嵌套字典取值
這篇文章主要介紹了如何利用python實(shí)現(xiàn)列表嵌套字典取值,首先通過(guò)將列表backup_unit_id全部提取出來(lái),確定需要取值的對(duì)象展開(kāi)文章內(nèi)容,感興趣的朋友可以看一下2022-06-06python簡(jiǎn)單實(shí)現(xiàn)刷新智聯(lián)簡(jiǎn)歷
本文給大家分享的是個(gè)人弄的一個(gè)使用Python簡(jiǎn)單實(shí)現(xiàn)刷新智聯(lián)招聘簡(jiǎn)歷的小工具的代碼,非常的簡(jiǎn)單,給大家參考下吧。2016-03-03