2013-10-10 36 views
2

嗨我想從ndarray派生一個類。我堅持在docs找到的配方,但我得到一個錯誤,我不明白,當我屁股getiem()函數。我確信這是它應該如何工作,但我不明白如何正確地做到這一點。我的班,基本上增加了一個「dshape」屬性的樣子:從ndarray調用傳承__getitem__

class Darray(np.ndarray): 
    def __new__(cls, input_array, dshape, *args, **kwargs): 
     obj = np.asarray(input_array).view(cls) 
     obj.SelObj = SelObj 
     obj.dshape = dshape 
     return obj 

    def __array_finalize__(self, obj): 
     if obj is None: return 
     self.info = getattr(obj, 'dshape', 'N') 

    def __getitem__(self, index):   
     return self[index] 

當我現在嘗試做:

D = Darray(ones((10,10)), ("T","N")) 

解釋將失敗,最大深度遞歸,因爲他所說的的GetItem一遍又一遍地。

有人可以向我解釋爲什麼以及如何實現getitem功能?

歡呼聲, 大衛

+3

作爲一個側面說明,你可能實際上並不_want_實現自定義的'__getitem__'上'ndarray'你可能會和一個陣列的行名關聯,因爲(除非你直接通過,或者代碼與基類完全相同),ufuncs/broadcasting將不會像索引它那樣看到你的數組。那麼,你究竟想在這裏做什麼? – abarnert

+0

這聽起來很有趣,我可以請你或任何人詳細說明這個話題,或者節省你的時間來指出這個問題的參考嗎?我會很感激。 – Magellan88

回答

4

可有人向我解釋爲什麼和如何實現getitem函數?

對於您當前的代碼,不需要__getitem__。當我刪除__getitem__實現時,您的課程正常工作(除未定義的SelObj外)。

最大遞歸深度誤差的原因是__getitem__的定義,它使用self[index]self.__getitem__(index)的簡寫符號。如果你必須重寫__getitem__,然後確保你調用父類實現的__getitem__

def __getitem__(self, index): 
    return super(Darray, self).__getitem__(index) 

至於爲什麼你應該這樣做:有很多的原因,覆蓋該功能,例如

class NamedRows(np.ndarray): 
    def __new__(cls, rows, *args, **kwargs): 
     obj = np.asarray(*args, **kwargs).view(cls) 
     obj.__row_name_idx = dict((n, i) for i, n in enumerate(rows)) 
     return obj 

    def __getitem__(self, idx): 
     if isinstance(idx, basestring): 
      idx = self.__row_name_idx[idx] 
     return super(NamedRows, self).__getitem__(idx) 

演示:

>>> a = NamedRows(["foo", "bar"], [[1,2,3], [4,5,6]]) 
>>> a["foo"] 
NamedRows([1, 2, 3]) 
3

的問題是在這裏:

def __getitem__(self, index):   
    return self[index] 

foo[index]只是調用foo.__getitem__(index)。但在你的情況,這只是返回foo[index],這只是調用foo.__getitem__(index)。它會在無限循環中重複,直到堆棧空間用完。

如果你想推遲到你的父類,你必須這樣做:

def __getitem__(self, index):   
    return super(Darray, self)[index] 

...或者,也許更明確:

def __getitem__(self, index):   
    return super(Darray, self).__getitem__(index) 
+0

謝謝你的回答也給出了正確的解釋,但我希望你不會介意接受後者爲包含的例子。 – Magellan88