copy --- 淺層 (shallow) 和深層 (deep) 復(fù)制操作?
源代碼: Lib/copy.py
Python 中賦值語句不復(fù)制對象,而是在目標(biāo)和對象之間創(chuàng)建綁定 (bindings) 關(guān)系。對于自身可變或者包含可變項的集合對象,開發(fā)者有時會需要生成其副本用于改變操作,進(jìn)而避免改變原對象。本模塊提供了通用的淺層復(fù)制和深層復(fù)制操作(如下所述)。
接口摘要:
-
copy.copy(x)? 返回 x 的淺層復(fù)制。
-
copy.deepcopy(x[, memo])? 返回 x 的深層復(fù)制。
-
exception
copy.error? 針對模塊特定錯誤引發(fā)。
淺層復(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ù))。
The deepcopy() function avoids these problems by:
保留在當(dāng)前復(fù)制過程中已復(fù)制的對象的 "備忘錄" (
memo) 字典;以及允許用戶定義的類重載復(fù)制操作或復(fù)制的組件集合。
該模塊不復(fù)制模塊、方法、棧追蹤(stack trace)、棧幀(stack frame)、文件、套接字、窗口、數(shù)組以及任何類似的類型。它通過不改變地返回原始對象來(淺層或深層地)“復(fù)制”函數(shù)和類;這與 pickle 模塊處理這類問題的方式是相似的。
制作字典的淺層復(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)傳入一個參數(shù)即 memo 字典。 如果 __deepcopy__() 實現(xiàn)需要創(chuàng)建一個組件的深層拷貝,它應(yīng)當(dāng)調(diào)用 deepcopy() 函數(shù)并以該組件作為第一個參數(shù),而將 memo 字典作為第二個參數(shù)。
參見
- 模塊
pickle 討論了支持對象狀態(tài)檢索和恢復(fù)的特殊方法。
