copy — 淺層和深層複製操作

原始碼: Lib/copy.py


Python 中的賦值語句不會複製物件,它們會在目標和物件之間建立繫結。對於可變或包含可變項的集合,有時需要複製,以便可以更改一個副本而不更改另一個副本。此模組提供通用的淺層和深層複製操作(如下所述)。

介面摘要

copy.copy(obj)

返回 obj 的淺層副本。

copy.deepcopy(obj[, memo])

返回 obj 的深層副本。

copy.replace(obj, /, **changes)

建立一個與 obj 型別相同的新物件,並用 changes 中的值替換欄位。

3.13 版本新增。

exception copy.Error

為模組特定錯誤引發。

淺層複製和深層複製之間的區別僅與複合物件(包含其他物件的物件,例如列表或類例項)相關

  • 淺層複製 構造一個新的複合物件,然後(在可能的範圍內)將引用插入到原始物件中找到的物件中。

  • 深層複製 構造一個新的複合物件,然後遞迴地將原始物件中找到的物件的副本插入到其中。

深層複製操作通常存在兩個淺層複製操作不存在的問題

  • 遞迴物件(直接或間接包含對其自身的引用的複合物件)可能會導致遞迴迴圈。

  • 因為深層複製會複製所有內容,所以它可能會複製太多,例如打算在副本之間共享的資料。

deepcopy() 函式透過以下方式避免這些問題:

  • 保留一個 memo 字典,其中包含當前複製過程中已複製的物件;並且

  • 允許使用者定義的類重寫複製操作或複製的元件集。

此模組不復制模組、方法、堆疊跟蹤、堆疊幀、檔案、套接字、視窗或任何類似型別。它透過返回未更改的原始物件來“複製”函式和類(淺層和深層);這與 pickle 模組處理這些物件的方式相容。

可以使用 dict.copy() 進行字典的淺層複製,使用整個列表的切片進行列表的淺層複製,例如,copied_list = original_list[:]

類可以使用相同的介面來控制複製,這些介面用於控制 pickling。有關這些方法的資訊,請參閱模組 pickle 的描述。實際上,copy 模組使用 copyreg 模組中註冊的 pickle 函式。

為了讓類定義自己的複製實現,它可以定義特殊方法 __copy__()__deepcopy__()

object.__copy__(self)

呼叫以實現淺層複製操作;不傳遞其他引數。

object.__deepcopy__(self, memo)

呼叫以實現深層複製操作;它傳遞一個引數,即 memo 字典。如果 __deepcopy__ 實現需要對元件進行深層複製,則應將元件作為第一個引數,將 memo 字典作為第二個引數來呼叫 deepcopy() 函式。memo 字典應被視為不透明物件。

函式 copy.replace()copy()deepcopy() 的功能更有限,僅支援由 namedtuple()dataclasses 和其他定義方法 __replace__() 的類建立的命名元組。

object.__replace__(self, /, **changes)

此方法應建立一個相同型別的新物件,並用 changes 中的值替換欄位。

另請參閱

模組 pickle

關於用於支援物件狀態檢索和恢復的特殊方法的討論。