2012年4月8日 星期日

[Python Std Library] Data Types : copy — Shallow and deep copy operations

翻譯自 這裡 
Preface : 
透過這個模組, 讓你可以選擇 shallow copy 或 deep copy 的操作. 而模組上的兩個介面如下 : 
copy.copy(x) 
Return a shallow copy of x.

copy.deepcopy(x) 
Return a deep copy of x.

另外包含一個例外 : 
exception copy.error 
Raised for module specific errors.

而所謂的 Deep copy 與 Shallow copy 只在 compound 物件上才會發生差異 (如 list, 或類別上包含其他類別的資訊 etc) : 
* A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
* A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

但在 Deep copy 可能會發生下面問題 : 
* Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.
* Because deep copy copies everything it may copy too much, e.g., administrative data structures that should be shared even between copies.

因此 deepcopy() 為了避免這些問題, 有如下措施 : 
* keeping a “memo” dictionary of objects already copied during the current copying pass; and
* letting user-defined classes override the copying operation or the set of components copied.

另外 copy 動作也不是無差別, 參考下面說明 : 
This module does not copy types like module, method, stack trace, stack frame, file, socket, window, array, 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.

其實如果你是要對 dict 進行 shallow copy, list 物件上面已經有對應函數 dict.copy(), 甚至你可以使用 slice 的方式進行 copy 如 copied_list = original_list[:]

Changed in version 2.5: Added copying functions. 
Classes can use the same interfaces to control copying that they use to control pickling. See the description of module pickle for information on these methods. The copy module does not use the copy_reg registration module.

最後為了讓自訂義類別可以決定自己的 copy 過程, 有兩個特殊函數 __copy__() 與 __deepcopy__() 可以進行設定. 第一個是用來在 shallow copy 操作 時使用(無參數) ; 第二個則是使用於 deep copy 操作 , 傳入參數為 memo dictionary 且 : 
If the __deepcopy__() implementation needs to make a deep copy of a component, it should call the deepcopy() function with the component as first argument and the memo dictionary as second argument.

Example : 
接著來看簡單範例, 了解 deep copy 與 shallow copy 的差異 : 

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...