2013-03-28 67 views
10

這是最容易實現用C拷貝構造函數(或重載賦值運算符)++因爲沒有指針的概念的情況。不過,我對如何在Python中實現淺層和深層複製感到困惑。的Python:淺及深拷貝構造函數的實現

我知道有在圖書館的一個特殊的命令,但他們不會對你自己編寫的類工作。那麼通用的方法是什麼?

P.S.顯示一些基本數據結構(鏈表或樹)的過程將不勝感激。

編輯:謝謝,他們的工作,這是我在語法上的錯誤。 我非常有興趣用__copy__()__deep_copy()__覆蓋這些函數。例如。如何在不知道數據結構中的哪種類型的信息的情況下製作深層副本?

+5

你是什麼意思,圖書館不適用於你自己設計的類? 'copy.copy'和'copy.deepcopy'有什麼問題? –

回答

22

蟒蛇copy module可以重用pickle module接口,讓類定製複製行爲。

自定義類的實例的默認值是創建一個新的空類,換出__class__屬性,然後對於淺拷貝,只需使用原始值更新副本上的__dict__即可。取而代之的是深度複製通過__dict__遞歸。

否則,你指定一個__getstate__()方法返回內部狀態。這可以是你的班級__setstate__()可以再次接受的任何結構。

您還可以指定__copy__()和/或__deepcopy__()方法來控制只需複製行爲。預計這些方法會自行完成所有複製,__deepcopy__()方法會傳遞一個備忘錄映射以傳遞給deepcopy()遞歸調用。

一個例子可以是:

from copy import deepcopy 

class Foo(object): 
    def __init__(self, bar): 
     self.bar = bar 
     self.spam = expression + that * generates - ham # calculated 

    def __copy__(self): 
     # self.spam is to be ignored, it is calculated anew for the copy 
     # create a new copy of ourselves *reusing* self.bar 
     return type(self)(self.bar) 

    def __deepcopy__(self, memo): 
     # self.spam is to be ignored, it is calculated anew for the copy 
     # create a new copy of ourselves with a deep copy of self.bar 
     # pass on the memo mapping to recursive calls to copy.deepcopy 
     return type(self)(deepcopy(self.bar, memo)) 

這個例子定義自定義複印掛鉤,防止self.spam被複制過,作爲一個新的實例將重新計算。

+0

我對最後一個解決方案非常感興趣。如何在不知道類型的情況下複製另一個值?我應該只寫所有類型還是有更簡單的解決方案? –

+1

@KudayarPirimbaev:您將包含的值委託給「copy.deepcopy」遞歸調用。它會處理不同的類型。 –

+0

謝謝,我明白了這一點 –