2010-06-14 27 views
4

我想重寫__deepcopy__對於一個給定的SQLAlchemy映射類,使它忽略任何SQLA屬性,但是深入瞭解類的一部分。如何在Python中「覆蓋」deepcopy?

我不是特別熟悉重寫Python的任何內置對象,但我對我想要的有一些想法。

我們來做一個非常簡單的類User,它使用SQLA映射。

class User(object): 
    def __init__(self, user_id=None, name=None): 
     self.user_id = user_id 
     self.name = name 

我用dir()看到,映射之前和之後,有什麼SQLAlchemy的特有屬性,也有和我發現_sa_class_manager_sa_instance_state

Questions
提供的是唯一的我怎麼會忽略定義__deepcopy__時?
此外,SQLA注入到映射對象中是否有任何屬性?


(我問這個前一個問題(如幾天後,我選擇了一個答案的主要問題,儘管編輯),但我想我錯過了火車那裏。道歉說。)


Edit - Fixed code thanks to zifot's answer

我下了Python文檔的唯一的事情是,你需要用memo定義deepcopy的一個額外的參數。周圍挖的卻有點後,我嘗試了這一點:

def __deepcopy__(self, memo): 
    dpcpy = self.__class__() 
    memo[id(self)] = dpcpy 
    for attr in dir(self): 
     if not attr.startswith('_'): 
      value = getattr(self, attr) 
      setattr(dpcpy, attr, copy.deepcopy(value, memo)) 
    return dpcpy 

然後我創建的User實例爲:

snake = User(913, 'Snake,S.') 

在那之後,我嘗試了deepcopy操作:

snake_dc = copy.deepcopy(snake) 

...和snake_dc仍然具有SQLA屬性...

我很樂意提供幫助,建議等

回答

0

我不是deepcopy方面的專家,但是從錯誤看起來您需要一個無參數構造函數來調用self.__class__()而不帶參數。

+0

對不起,你是什麼意思 「參數的構造函數」 是什麼意思? – PizzAzzra 2010-06-14 12:09:44

+0

對不起。一個'__init__',它不需要超出自身的變量。查看zifot的答案作爲例子。 – mavnn 2010-06-14 12:19:10

+0

他的意思是說你的User .__ init__函數(「構造函數」,雖然技術上它不是構造函數)有三個參數:self,user_id和name,但是當你調用self .__ class __()時,你只傳遞第一個一個(隱含地)。 – zifot 2010-06-14 12:21:52

1

mavnn is right。例如試試你的用戶的初始化更改爲:

def __init__(self, user_id = None, name = None): 
     self.user_id = user_id 
     self.name = name 

至於複製映射的情況下,我建議你閱讀this thread

+0

謝謝。爲'User'更改了'__init__',但不幸的是'snake_dc'似乎具有完整的SQLA屬性:S – PizzAzzra 2010-06-14 12:38:04

+0

那是哪個? – zifot 2010-06-14 12:54:59

+0

'_sa_class_manager','_sa_instance_state' – PizzAzzra 2010-06-14 16:22:59

0

要排除的SQLAlchemy列和映射的屬性,你會做線沿線的東西:

for attr in dir(self): 
    if not self._sa_class_manager.mapper.has_property(key): 
     ... 
1

當(深)複製時,您不應該調用__init__,而是調用__new__

一個例子:

def __copy__(self): 
    cls = self.__class__ 
    newobject = cls.__new__(cls) 
    newobject.__dict__.update(self.__dict__) 
    return newobject 
+0

+1 Rob Young在以下評論中明確表示了這一點:http://stackoverflow.com/questions/1500718/what-is-the-right-way-to-override-the-copy-deepcopy-operations-on-an -object-IN-p – ponadto 2017-02-17 08:09:58