2010-07-15 57 views
4

好的......這可能是一個愚蠢的問題......但我現在沒有找到答案!Python副本:如何繼承默認的複製行爲?

我需要實現一個對象的副本,爲此我想要複製所有屬性,除了一個或兩個我想完全控制副本的副本外。

這裏是對象的標準複製行爲:

>>> class test(object): 
...  def __init__(self, arg): 
...   self._a = arg 
... 
>>> t = test(123999) 
>>> t._a 
123999 
>>> tc = copy.copy(t) 
>>> tc._a 
123999 

這基本上意味着所有的屬性被複制。我想這樣做的是重新使用此行爲以下列方式:

>>> class test(object): 
...  def __init__(self, arga, argb): 
...   self._a = arga 
...   self._b = argb 
... 
...  def __copy__(self): 
...   obj_copy = copy.copy(self) #NOT POSSIBLE OF COURSE => infinite recursion 
...   obj_copy._b = my_operation(obj_copy._b) 
...   return obj_copy 

我希望你有一點:我想重新使用該對象的複製行爲,但鉤在我自己的操作。有沒有乾淨的方式來做到這一點(無需做for attr_name in dir(self): ...)?

+0

如果你是比較新的Python和你認爲你需要複製一個對象,你可能錯了,除非你能解釋一下到底爲什麼副本做一些事情,對象本身不能。 – msw 2010-07-15 08:06:25

+0

我已經有一段時間了,我做了一些Python ...並相信我,我知道我必須複製這次! – sebpiq 2010-07-15 08:21:52

回答

5

你可能只是做:

def __copy__(self): 
    clone = copy.deepcopy(self) 
    clone._b = some_op(clone._b) 
    return clone 

這工作,因爲deepcopy避免遞歸。從python docs

的deepcopy的()函數通過避免了這些問題: 保持當前複印通過期間已複製的對象的一個​​「備忘錄」字典;和 讓用戶定義的類覆蓋複製操作或複製的組件集。

+0

所有答案都很好,但實際上這是最簡單的...謝謝! – sebpiq 2010-07-15 08:20:01

3

如果沒有性能& C,所有的狀態在__dict__,所以...:

...  def __copy__(self): 
...   obj_copy = object.__new__(type(self)) 
...   obj_copy.__dict__ = self.__dict__.copy() 
...   obj_copy._b = my_operation(obj_copy._b) 
...   return obj_copy 
1

我想做到這一點通過以下方式 - 試試吧:

import copy 
class test(object): 
    def __init__(self, **args): 
     self.args = args 

    def __copy__(self): 
     obj_copy = copy.deepcopy(self) 
     return obj_copy