2011-05-15 52 views
2

我想編寫一個類,該子類將Python列表子類化,並在列表更改時通知某個其他對象。因爲有許多需要覆蓋的方法,我選擇的,而不是壓倒一切的是改變列表中的所有方法,像這樣的解決方案,:替換Python列表對象的特殊方法

destructiveMethods = ["__setitem__", 
         "__setslice__", 
         "__delitem__", 
         "__delslice__", 
         "append", 
         "extend", 
         "remove", 
         "reverse", 
         "sort"] 

class OwnedList(list): 
    def __init__(self, owner, initValue=[]): 
     super(OwnedList, self).__init__(initValue) 


     def wrappedMethod(method): 
      def resultMethod(*args, **kwargs): 
       ret = method(*args, **kwargs) 
       self.owner.notify() 
       return ret 
      return resultMethod 

     self.owner = owner 
     for m in destructiveMethods: 
      setattr(self, m, wrappedMethod(getattr(self, m))) 

此工程的方法,如「追加」,而不是特殊的方法,如「__setitem__」。對於那些,我只是得到舊的方法。

我發現,如果我打印的,比方說,附加的價值,我得到的是這樣的:

<built-in method append of list object at 0x267a7a0> 

但__setitem__(在香草名單)這就是我得到:

<method-wrapper '__setitem__' of list object at 0x266fd40> 

也許這與我的問題有關。

任何幫助表示讚賞。如果你知道完成我需要做的更好的方法,請分享你的想法。謝謝。

UPDATE: 別的東西,我已經注意到呼籲__setitem__直接在OwnedList對象上正常工作,但使用括號沒有。

回答

2

特殊方法只能定義對象的類型而不能定義實例source

比較

>>> class A(object): 
...  __getitem__ = lambda self,i: 42 
>>> A()[0] 
42 

>>> class B(object): 
...  def __init__(self): 
...    self.__getitem__ = lambda self,i: 42 
>>> B()[0] 
TypeError: 'B' object does not support indexing 

你應該適應A,即直接在類體內定義你的特殊的方法,而不是在構造函數中。

+0

謝謝。奇蹟般有效。 – Elektito 2011-05-15 13:35:54