對于拷貝這個問題,個人感覺還是很有意思的。在這里我也僅僅闡述一下個人的認識,如果不對的話還希望各位大佬及時指出,我們互相學(xué)習(xí)。
淺拷貝
當(dāng)直接使用等號,函數(shù)參數(shù)傳遞,使用copy庫中的copy方法時均為淺拷貝。對于淺拷貝的含義,我們通過一個例子進行說明。

畫的有點長了,勉強看吧。圖1.1表示當(dāng)執(zhí)行a=1時,數(shù)據(jù)1會被放置到內(nèi)存#6處,其引用a在內(nèi)存#3處。圖1.2表示當(dāng)發(fā)生淺拷貝時,數(shù)據(jù)1不會發(fā)生變化,只會產(chǎn)生另一個引用b放置在內(nèi)存#4處,同時指向數(shù)據(jù)1的內(nèi)存地址#6。圖1.3表示當(dāng)對a進行修改了,其便不再是數(shù)據(jù)1的引用了,指向了數(shù)據(jù)3的地址#7,成為了數(shù)據(jù)3的引用,但是并沒有影響b,所以不會對其產(chǎn)生影響。
也就是說當(dāng)發(fā)生淺拷貝時,原來存儲數(shù)據(jù)的內(nèi)存空間并不發(fā)生變化,而是多了一個引用而已。所以當(dāng)對其中一個引用進行修改時并不會影響另一個引用,但是如果通過一個引用修改了對應(yīng)數(shù)據(jù)內(nèi)存中的值,這就影響到了另一個引用,參考下圖。

因為執(zhí)行了a.append(3),這實際上將6號內(nèi)存中的數(shù)據(jù)進行了修改,所以會影響b。
其實在這個地方涉及到Python中數(shù)據(jù)類型的,這里稍微提一下數(shù)據(jù)類型。
- 不可變類型:數(shù)值型常量,元組tuple,字符串
- 可變類型:字典dict,列表list,集合set
現(xiàn)在很多文章在分析前拷貝時是將可變和不可變區(qū)分開進行闡述的,實際上我覺得并沒有這個必要。
因為不可變變量是無法進行修改的,所以能改的只有其引用,引用一改就不再指向不可變變量的內(nèi)存空間了,所以修改了一個引用之后并不會對其他的引用產(chǎn)生影響,比如圖1。
如果是可變的變量,那么是可以通過其引用對其進行修改的,比如圖2通過引用a往列表中添加了元素,這并沒有改變引用的指向,所以肯定會影響另一個引用的。
深拷貝
OK,說完了淺拷貝,接下來就是深拷貝了。使用深拷貝是通過copy庫的deepcopy方法實現(xiàn)的。之所以引入深拷貝可能是因為像圖2這種情況將數(shù)據(jù)做了修改,使得所有引用都受到了影響。這在我做劍指Offer面試題12的時候遇到了。(http://www.itdecent.cn/p/223fe4484457)
同樣舉個例子對其進行說明。

從圖中可以看出,深拷貝是將數(shù)據(jù)直接拷貝了一份,然后新的引用是指向新的數(shù)據(jù)內(nèi)存地址的,所以對兩個引用做修改時肯定不會互相影響的。
作者原創(chuàng),如需轉(zhuǎn)載及其他問題請郵箱聯(lián)系:lwqiang_chn@163.com。
個人網(wǎng)站:https://www.myqiang.top。