一、數(shù)據(jù)類型
數(shù)據(jù)分為基本數(shù)據(jù)類型(String, Number, Boolean, Null, Undefined,Symbol)和對(duì)象數(shù)據(jù)類型。
基本數(shù)據(jù)類型的特點(diǎn):直接存儲(chǔ)在棧(stack)中的數(shù)據(jù)
引用數(shù)據(jù)類型的特點(diǎn):存儲(chǔ)的是該對(duì)象在棧中引用,真實(shí)的數(shù)據(jù)存放在堆內(nèi)存里
引用數(shù)據(jù)類型在棧中存儲(chǔ)了指針,該指針指向堆中該實(shí)體的起始地址。當(dāng)解釋器尋找引用值時(shí),會(huì)首先檢索其在棧中的地址,取得地址后從堆中獲得實(shí)體。

二、淺拷貝與深拷貝
2.1 概述:
淺拷貝可以使用列表自帶的copy()函數(shù)(如list.copy()),或者使用copy模塊的copy()函數(shù)。深拷貝只能使用copy模塊的deepcopy(),所以使用前要導(dǎo)入:from copy import deepcopy
深拷貝和淺拷貝是只針對(duì)Object和Array這樣的引用數(shù)據(jù)類型的。
如果拷貝的對(duì)象里的元素只有值,沒有引用,那淺拷貝和深拷貝沒有差別,都會(huì)將原有對(duì)象復(fù)制一份,產(chǎn)生一個(gè)新對(duì)象,對(duì)新對(duì)象里的值進(jìn)行修改不會(huì)影響原有對(duì)象,新對(duì)象和原對(duì)象完全分離開。
如果拷貝的對(duì)象里的元素包含引用(像一個(gè)列表里儲(chǔ)存著另一個(gè)列表,存的就是另一個(gè)列表的引用),那淺拷貝和深拷貝是不同的,淺拷貝雖然將原有對(duì)象復(fù)制一份,但是依然保存的是引用,所以對(duì)新對(duì)象里的引用里的值進(jìn)行修改,依然會(huì)改變?cè)瓕?duì)象里的列表的值,新對(duì)象和原對(duì)象并沒有完全分離開。而深拷貝則不同,它會(huì)將原對(duì)象里的引用也新創(chuàng)建一個(gè),即新建一個(gè)列表,然后放的是新列表的引用,這樣就可以將新對(duì)象和原對(duì)象完全分離開。
2.2 實(shí)現(xiàn)原理
具體過程詳見以下連接:https://blog.csdn.net/qq_34493908/article/details/81560546
【1】淺拷貝:
aa=[1,2,3,[4,5]]
bb=copy(aa) # 使用copy()函數(shù)對(duì)aa進(jìn)行拷貝賦值給bb
bb[3][0]=9 #修改bb列表里[4,5]中的4為9
對(duì)于bb=copy(aa)的操作,其在內(nèi)存當(dāng)中的示意圖如下:

因此,當(dāng)我們執(zhí)行到bb[3][0]=9這塊代碼時(shí):其在內(nèi)存當(dāng)中實(shí)際操作如下:

顯然,bb里的值改變了,aa里的值也改變了,即證實(shí):
淺拷貝雖然將原有對(duì)象復(fù)制一份,但是依然保存的是引用,所以對(duì)新對(duì)象里的引用里的值進(jìn)行修改,依然會(huì)改變?cè)瓕?duì)象里的列表的值,新對(duì)象和原對(duì)象并沒有完全分離開。
【2】深拷貝
aa=[1,2,3,[4,5]]
bb=deepcopy(aa) #使用deepcopy()函數(shù)對(duì)aa進(jìn)行深拷貝賦值給bb
bb[3][0]=9 #修改bb列表里[4,5]中的4為9
對(duì)于bb=deepcopy(aa)的操作,其在內(nèi)存當(dāng)中的示意圖如下:

因此,當(dāng)我們執(zhí)行到bb[3][0]=9這塊代碼時(shí):其在內(nèi)存當(dāng)中實(shí)際操作如下:

顯然:很明顯只改變bb列表里列表[4,5]中的4為9,aa中的沒有改變,因?yàn)樗璦a列表指向的引用是不同的。這也充分驗(yàn)證了這句話:
而深拷貝則不同,它會(huì)將原對(duì)象里的引用也新創(chuàng)建一個(gè),即新建一個(gè)列表,然后放的是新列表的引用,這樣就可以將新對(duì)象和原對(duì)象完全分離開
四、深拷貝和淺拷貝的示意圖:

淺拷貝只復(fù)制指向某個(gè)對(duì)象的指針,而不復(fù)制對(duì)象本身,新舊對(duì)象還是共享同一塊內(nèi)存。但深拷貝會(huì)另外創(chuàng)造一個(gè)一模一樣的對(duì)象,新對(duì)象跟原對(duì)象不共享內(nèi)存,修改新對(duì)象不會(huì)改到原對(duì)象。
五、賦值和淺拷貝的區(qū)別
當(dāng)我們把一個(gè)對(duì)象賦值給一個(gè)新的變量時(shí),賦的其實(shí)是該對(duì)象的在棧中的地址,而不是堆中的數(shù)據(jù)。也就是兩個(gè)對(duì)象指向的是同一個(gè)存儲(chǔ)空間,無(wú)論哪個(gè)對(duì)象發(fā)生改變,其實(shí)都是改變的存儲(chǔ)空間的內(nèi)容,因此,兩個(gè)對(duì)象是聯(lián)動(dòng)的。
淺拷貝是按位拷貝對(duì)象,它會(huì)創(chuàng)建一個(gè)新對(duì)象,這個(gè)對(duì)象有著原始對(duì)象屬性值的一份精確拷貝。如果屬性是基本類型,拷貝的就是基本類型的值;如果屬性是內(nèi)存地址(引用類型),拷貝的就是內(nèi)存地址 ,因此如果其中一個(gè)對(duì)象改變了這個(gè)地址,就會(huì)影響到另一個(gè)對(duì)象。即默認(rèn)拷貝構(gòu)造函數(shù)只是對(duì)對(duì)象進(jìn)行淺拷貝復(fù)制(逐個(gè)成員依次拷貝),即只復(fù)制對(duì)象空間而不復(fù)制資源。
六、賦值、淺拷貝、深拷貝對(duì)原始數(shù)據(jù)的影響
