[Numpy-discussion] subclassing ndaray

Travis Oliphant oliphant.travis at ieee.org
Fri Feb 24 17:59:03 EST 2006

Colin J. Williams wrote:

> I have a subclass Bar, a 1-dim array which has some methods and some 
> attributes.  One of the attributes is a view of the Bar to permit 
> different shaping.

The ndarray handles sub-classing a little-bit differently.   All array 
constructors go through the same C-code call which can create 
sub-classes as well.    (it's what gets called by ndarray.__new__).

If there is a parent object, then additionally, the

__array_finalize__(self, parent)

method is called right-after creation of the sub-class.   This is where 
attributes should be finalized.  But, care must be taken in this code so 
that a recursion is not setup

If this mechanism is not sufficient for you, then you need to use a 
container class (for this reason UserArray has been resurrected to serve 
as a default container class model---it needs more testing, however). 

The problem __array_finalize__ helps fix is how to get subclasses to 
work well without having to re-define every single special method like 
UserArray does.

For the most part it seems to work, but I suppose it creates a few 
surprises if you are not aware of what is going on.

The most important thing to remember is that attributes are not 
automatically carried over to new instances because new instances can be 
created without every calling __new__ or __init__.

I'm sure this mechanism can be improved upon and I welcome suggestions.

> Suppose that 'a' is an instance of 'Bar', which has a method 'show' 
> and a view attribute 'v'.
> a ^ 15 returns a Bar instance, with its methods but without the 
> attributes.
> I am attempt to change this, Bar has a method __xor__, see below:
>      def __xor__(self, other):
>        ''' Exclusive or: __xor__(x, y) => x ^ y . '''
>        z=
> 1                                                                    
>    <<  this loops to the recursion limit
>        result= ArrayType.__xor__(self, other)
>        n= self.n
>        result.n= n
>        result.rowSize= self.rowSize
>        result.show= self.show
>        result.v= _n.reshape(result.view(), (n*n, n*n))
>        return result

Look at the __array_finalize__ method in defmatrix.py for ideas about 
how it can be used.


More information about the NumPy-Discussion mailing list