Python 从ndarray调用继承uu getitem__

Python 从ndarray调用继承uu getitem__,python,numpy,Python,Numpy,嗨,我正试图从ndarray派生一个类。我坚持在中找到的配方,但当我重写\uu getiem\uu()函数时,我遇到了一个我不理解的错误。我相信这就是它应该如何工作,但我不知道如何正确地做。我的类基本上添加了一个“dshape”属性,如下所示: class Darray(np.ndarray): def __new__(cls, input_array, dshape, *args, **kwargs): obj = np.asarray(input_array).vie

嗨,我正试图从ndarray派生一个类。我坚持在中找到的配方,但当我重写
\uu getiem\uu()
函数时,我遇到了一个我不理解的错误。我相信这就是它应该如何工作,但我不知道如何正确地做。我的类基本上添加了一个“dshape”属性,如下所示:

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"))
解释器将以最大深度递归失败,因为他反复调用
\uuu getitem\uuu

有人能给我解释一下为什么以及如何实现getitem函数吗

干杯, David

问题在于:

def __getitem__(self, index):        
    return self[index]
foo[index]
只需调用
foo.\uu getitem\uuuu(index)
。但在您的例子中,它只返回
foo[index]
,它只调用
foo.\uu getitem\uuu(index)
。在无限循环中重复,直到堆栈空间用完

如果要遵从父类,必须执行以下操作:

def __getitem__(self, index):        
    return super(Darray, self)[index]
…或者,更明确地说:

def __getitem__(self, index):        
    return super(Darray, self).__getitem__(index)
有人能给我解释一下为什么以及如何实现getitem函数吗

对于当前代码,不需要
\uuuu getitem\uuu
。当我删除
\uu getitem\uu
实现时,您的类运行良好(除了未定义的
SelObj

最大递归深度错误的原因是
\uuuu getitem\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。如果必须重写
\uuuuuu getitem\uuuu
,请确保调用
\uuuuu getitem\uuuu
的超类实现:

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)
演示:


我不明白为什么要从
np.ndarray
type继承类。您可以使用标准OOP方法实现与上述相同的思想。下面的示例与您的代码做了相同的事情,但更简单。我不是子类化,而是将numpy数组作为特殊对象的一个成员,该对象也包含
dshape
。它只创建
\uuuu getitem\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

class Darray:
    def __init__(self, input_array, dshape):
        self.array = np.array(input_array)
        self.dshape = dshape

    def __getitem__(self, item):
        return self.array[item]

    def __setitem__(self, item, val):
        self.array[item] = val
现在,您可以编写进一步的方法来描述您想要的确切行为。无论
dhape
应该对继承的数组做什么,现在都应该对
self.array
成员做什么

这种方法的另一个好处是不存在递归深度、或
\uu数组\u finalize\uu
、或
super()
、或在此子类化和重载过程中可能出现的任何其他陷阱。对于预期的用例,总是有一种更简单的方法

编辑:在我上面的示例中,
\uu getitem\uu
方法不适用于
用于
N
维度数组的分隔索引。解决这个问题

    def __getitem__(self, *args):
        return self.array.__getitem__(*args)

作为补充说明,您可能实际上不想在
ndarray
上实现自定义
\uuuuu getitem\uuuuuu
,因为(除非您直接通过,或者代码与基类完全相同)ufuncs/broadcasting不会以索引数组的方式查看数组。那么,你到底想在这里做什么呢?听起来很有趣,我可以请你或任何人详细说明这个话题,或者节省你的时间来指出关于这个问题的参考资料吗?我将非常感激。谢谢你的回答也给出了正确的解释,但我希望你不介意接受后一个例子。
    def __getitem__(self, *args):
        return self.array.__getitem__(*args)