久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

圖解 Python 淺拷貝與深拷貝

 AnonymousV臉 2018-10-06

Python 中的賦值語句不會(huì)創(chuàng)建對(duì)象的拷貝,,僅僅只是將名稱綁定至一個(gè)對(duì)象,。對(duì)于不可變對(duì)象,通常沒什么差別,,但是處理可變對(duì)象或可變對(duì)象的集合時(shí),,你可能需要?jiǎng)?chuàng)建這些對(duì)象的 “真實(shí)拷貝”,也就是在修改創(chuàng)建的拷貝時(shí)不改變?cè)嫉膶?duì)象,。

本文將以圖文方式介紹 Python 中復(fù)制或“克隆”對(duì)象的操作,。

首先介紹一下 Python 中淺拷貝與深拷貝的區(qū)別:

淺拷貝:淺拷貝意味著構(gòu)造一個(gè)新的集合對(duì)象,然后用原始對(duì)象中找到的子對(duì)象的引用來填充它,。從本質(zhì)上講,,淺層的復(fù)制只有一層的深度。復(fù)制過程不會(huì)遞歸,,因此不會(huì)創(chuàng)建子對(duì)象本身的副本,。

深拷貝:深拷貝使復(fù)制過程遞歸。這意味著首先構(gòu)造一個(gè)新的集合對(duì)象,,然后遞歸地用在原始對(duì)象中找到的子對(duì)象的副本填充它,。以這種方式復(fù)制一個(gè)對(duì)象,遍歷整個(gè)對(duì)象樹,,以創(chuàng)建原始對(duì)象及其所有子對(duì)象的完全獨(dú)立的克隆,。

賦值與引用

在開始淺拷貝與深拷貝前,我們先來看一下 Python 中的賦值與引用,。

從字面上看,,上述語句創(chuàng)建了變量和,并且和的賦值都為一個(gè)列表,。但是,,Python 的賦值語句并不會(huì)復(fù)制對(duì)象,,而是會(huì)重新創(chuàng)建一個(gè)對(duì)象的引用。

可以看出,,和都引用了同一個(gè)列表,。

創(chuàng)建淺拷貝

不少教程里都會(huì)提到,如果你有一個(gè)列表,,當(dāng)你想要修改列表中的值但卻不想影響原始對(duì)象時(shí),,可以使用 復(fù)制(淺拷貝)一個(gè)列表。

我們先來試一下:

沒錯(cuò),,和分別指向了不同的列表,。當(dāng)修改列表中的值時(shí),并不會(huì)對(duì)對(duì)象產(chǎn)生影響,。

之所以說 語句是淺拷貝,,是因?yàn)檫@種修改只對(duì)一層對(duì)象有效,當(dāng)列表中有子對(duì)象時(shí),,對(duì)子對(duì)象的修改將影響原始對(duì)象和淺拷貝對(duì)象,。

為了解釋這一說法,讓我們先創(chuàng)建一個(gè)嵌套列表,,并使用 函數(shù)創(chuàng)建淺拷貝。

這里是有著和一樣內(nèi)容的新的獨(dú)立的對(duì)象,。

可以看到 和 分別指向了不同的對(duì)象,。

對(duì)第一層 的修改,,將不會(huì)對(duì) 副本造成影響。

但是,,因?yàn)槲覀冎粍?chuàng)建了原始列表的一個(gè)淺拷貝,,所以 仍然包含對(duì) 中存儲(chǔ)的原始子對(duì)象的引用。

也就是如上圖所示,, 和 的子列表都指向了相同的對(duì)象,。

子對(duì)象沒有被復(fù)制,它們只是在復(fù)制的列表中被再次引用,。

因此,,當(dāng)你修改中的一個(gè)子對(duì)象時(shí),這種修改也會(huì)反映到中—— 這是因?yàn)閮蓚€(gè)列表共享相同的子對(duì)象,。這種復(fù)制只是一個(gè)淺的,,一個(gè)層級(jí)的復(fù)制:

如果我們?cè)诘谝徊街袆?chuàng)建了一個(gè) 的深拷貝,那么兩個(gè)對(duì)象就完全獨(dú)立了。這是對(duì)象的淺拷貝和深拷貝之間的實(shí)際區(qū)別,。

使用 Python 標(biāo)準(zhǔn)庫中的 模塊可以創(chuàng)建深拷貝,,這個(gè)模塊為創(chuàng)建任意 Python 對(duì)象的淺拷貝和深拷貝提供了一個(gè)簡單的接口。

創(chuàng)建深拷貝

這次我們使用 函數(shù)創(chuàng)建一個(gè)對(duì)象的深拷貝:

從圖中可以看出 和 中的子對(duì)象指向了不同的對(duì)象,,如果對(duì) 的子對(duì)象進(jìn)行修改,,將不會(huì)影響 。

這一次,,原始對(duì)象和復(fù)制對(duì)象都是完全獨(dú)立的,。如前面所說,,遞歸克隆了 ,包括它的所有子對(duì)象:

模塊中的函數(shù)也可以創(chuàng)建對(duì)象的淺拷貝,。使用可以明確地表示創(chuàng)建淺拷貝,。對(duì)于內(nèi)置集合,,簡單地使用、和等工廠函數(shù)來創(chuàng)建淺拷貝是更加 Pythonic 的,。

復(fù)制任意 Python 對(duì)象

和 函數(shù)可用于復(fù)制任意對(duì)象,。以前面的列表復(fù)制示例為基礎(chǔ)。讓我們從定義一個(gè)簡單的 2D 點(diǎn)類開始:

函數(shù)使我們可以輕松地在 Python 解釋器中檢查從這個(gè)類創(chuàng)建的對(duì)象,。

接下來,,我們將創(chuàng)建一個(gè) Point 實(shí)例,然后使用 模塊復(fù)制(淺拷貝)它:

和 分別指向了不同的 Point 實(shí)例,。因?yàn)槲覀兊?Point 對(duì)象使用不可變類型(int)作為其坐標(biāo),,所以在這種情況下,淺拷貝和深拷貝沒有區(qū)別,。但我馬上會(huì)展開這個(gè)例子,。

接下來定義另一個(gè)類來表示 2D 矩形。矩形將使用 Point 對(duì)象來表示它們的坐標(biāo):

跟前面 list 的例子一樣,,和的子對(duì)象都有相同的引用,。在對(duì)象層級(jí)中修改一個(gè)對(duì)象,,將看到這個(gè)變化也反映在淺拷貝的副本中:

接下來創(chuàng)建 Rectangle 的深拷貝并對(duì)其進(jìn)行修改:

可以看出,深拷貝完全獨(dú)立于原始對(duì)象和淺拷貝對(duì)象,。

參閱 copy 模塊文檔 可以對(duì)復(fù)制進(jìn)行進(jìn)一步的研究,。例如,對(duì)象可以通過定義特殊的方法 和 來控制如何復(fù)制它們,。

謹(jǐn)記三件事

創(chuàng)建對(duì)象的淺拷貝不會(huì)克隆子對(duì)象,。因此,拷貝不會(huì)完全獨(dú)立于原始對(duì)象,。

一個(gè)對(duì)象的深拷貝會(huì)遞歸地克隆子對(duì)象,。克隆對(duì)象完全獨(dú)立于原始對(duì)象,,但是創(chuàng)建深拷貝速度較慢,。

可以使用 模塊復(fù)制任意對(duì)象(包括自定義類)。

部分內(nèi)容翻譯自:

https:///copying-python-objects/

本文博客地址:

(完)

看完本文有收獲,?請(qǐng)轉(zhuǎn)發(fā)分享給更多人

關(guān)注「Python那些事」,,做全棧開發(fā)工程師

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多