【发布时间】:2011-09-08 02:52:35
【问题描述】:
我正在努力继承我自己的 numpy.ndarray 子类。我真的不明白问题出在哪里,希望有人解释在以下情况下出了什么问题以及如何做我想做的事情。
我想要达到的目标:
我有一个 numpy.ndarry 的子类,它的行为如我所愿(下面代码中的 A 类)。我想继承 A(下面代码中的 B 类),以便 B 包含附加信息(名称)和方法(装饰的 .simple_data 方法)。
案例一:
import numpy as np
class A(np.ndarray):
def __new__(cls,data):
obj = np.asarray(data).view(cls)
return obj
def __array_finalize(self,obj):
if obj is None: return
class B(A):
def __init__(self,data,name):
super(B,self).__init__(data)
self.name = name
@property
def simple_data(self):
return [data[0,:],data[:,0]]
if __name__ == '__main__':
data = np.arange(20).reshape((4,5))
b = B(data,'B')
print type(b)
print b.simple_data
运行此代码会产生输出:
Traceback (most recent call last):
File "ndsubclass.py", line 24, in <module>
b = B(data,'B')
TypeError: __new__() takes exactly 2 arguments (3 given)
我假设这与 B 的构造中的 'name' 变量有关,并且由于 A 是 numpy.array 的子类,因此 A 的 new 方法在 B 的 之前被调用>init 方法。因此,为了解决这个问题,我假设 B 还需要一个 new 方法来适当地处理附加参数。
我的猜测是这样的:
def __new__(cls,data,name):
obj = A(data)
obj.name = name
return obj
应该可以,但是如何改变obj的类呢?
案例2:
import numpy as np
class A(np.ndarray):
def __new__(cls,data):
obj = np.asarray(data).view(cls)
return obj
def __array_finalize__(self,obj):
if obj is None: return
class B(A):
def __new__(cls,data):
obj = A(data)
obj.view(cls)
return obj
def __array_finalize__(self,obj):
if obj is None: return
@property
def simple_data(self):
return [self[0,:],self[:,0]]
if __name__ == '__main__':
data = np.arange(20).reshape((4,5))
b = B(data)
print type(b)
print b.simple_data()
运行时输出为:
<class '__main__.A'>
Traceback (most recent call last):
File "ndsubclass.py", line 30, in <module>
print b.simple_data()
AttributeError: 'A' object has no attribute 'simple_data'
这出乎我的意料:
<class '__main__.B'>
[array([0, 1, 2, 3, 4]), array([ 0, 5, 10, 15])]
我假设 B.new() 中对 view() 的调用以某种方式未正确设置 obj 的类。为什么?
我对发生的事情感到困惑,如果有人能解释一下,我将不胜感激。
【问题讨论】:
标签: python numpy subclassing