Python 从ndarray调用继承uu getitem__
嗨,我正试图从ndarray派生一个类。我坚持在中找到的配方,但当我重写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
\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)