copy --- 淺層 (shallow) 和深層 (deep) 復(fù)制操作?

源代碼: Lib/copy.py


Python 的賦值語句不復(fù)制對象,而是創(chuàng)建目標(biāo)和對象的綁定關(guān)系。對于自身可變,或包含可變項的集合,有時要生成副本用于改變操作,而不必改變原始對象。本模塊提供了通用的淺層復(fù)制和深層復(fù)制操作,(如下所述)。

接口摘要:

copy.copy(x)?

返回 x 的淺層復(fù)制。

copy.deepcopy(x[, memo])?

返回 x 的深層復(fù)制。

exception copy.Error?

針對模塊特定錯誤引發(fā)。

淺層與深層復(fù)制的區(qū)別僅與復(fù)合對象(即包含列表或類的實例等其他對象的對象)相關(guān):

  • 淺層復(fù)制 構(gòu)造一個新的復(fù)合對象,然后(在盡可能的范圍內(nèi))將原始對象中找到的對象的 引用 插入其中。

  • 深層復(fù)制 構(gòu)造一個新的復(fù)合對象,然后,遞歸地將在原始對象里找到的對象的 副本 插入其中。

深度復(fù)制操作通常存在兩個問題, 而淺層復(fù)制操作并不存在這些問題:

  • 遞歸對象 (直接或間接包含對自身引用的復(fù)合對象) 可能會導(dǎo)致遞歸循環(huán)。

  • 由于深層復(fù)制會復(fù)制所有內(nèi)容,因此可能會過多復(fù)制(例如本應(yīng)該在副本之間共享的數(shù)據(jù))。

deepcopy() 函數(shù)用以下方式避免了這些問題:

  • 保留在當(dāng)前復(fù)制過程中已復(fù)制的對象的 "備忘錄" (memo) 字典;以及

  • 允許用戶定義的類重載復(fù)制操作或復(fù)制的組件集合。

This module does not copy types like module, method, stack trace, stack frame, file, socket, window, or any similar types. It does "copy" functions and classes (shallow and deeply), by returning the original object unchanged; this is compatible with the way these are treated by the pickle module.

制作字典的淺層復(fù)制可以使用 dict.copy() 方法,而制作列表的淺層復(fù)制可以通過賦值整個列表的切片完成,例如,copied_list = original_list[:]。

類可以使用與控制序列化(pickling)操作相同的接口來控制復(fù)制操作,關(guān)于這些方法的描述信息請參考 pickle 模塊。實際上,copy 模塊使用的正是從 copyreg 模塊中注冊的 pickle 函數(shù)。

想要為一個類定義它自己的拷貝操作實現(xiàn),可以通過定義特殊方法 __copy__()__deepcopy__()。 調(diào)用前者以實現(xiàn)淺層拷貝操作;該方法不必傳入額外參數(shù)。 調(diào)用后者以實現(xiàn)深層拷貝操作;它應(yīng)轉(zhuǎn)入一個參數(shù),即 memo 字典。 如果 __deepcopy__() 實現(xiàn)需要創(chuàng)建一個組件的深層拷貝,它應(yīng)當(dāng)調(diào)用 deepcopy() 函數(shù)并以該組件作為第一個參數(shù)而以該 memo 字典作為第二個參數(shù)。。 memo 字典應(yīng)當(dāng)被當(dāng)作不透明對象來處理。

參見

模塊 pickle

討論了支持對象狀態(tài)檢索和恢復(fù)的特殊方法。