[Numpy-discussion] Simplest ndarray subclass __new__ possible?

Zachary Pincus zpincus at stanford.edu
Sun Feb 26 21:35:01 CST 2006

Hi folks,

I'm trying to write an ndarray subclass with a constructor like the  
matrix constructor -- one which can take matrix objects, array  
objects, or things that can be turned into array objects.

I've copied the __new__ method from matrix (and tried to eliminate  
the matrix-specific stuff), but there's a lot of code there. So I'm  
trying to figure out what the absolute minimum I need is for correct  
behavior. (This would be a useful wiki entry somewhere. In fact, a  
whole page about subclassing ndarray would be good.)

What follows is what I have so far. Have I missed anything, or can  
anything else be removed?


class contour(numpy.ndarray):
   def __new__(subtype, data, dtype=None, copy=True):

##### Do I need this first if block?
##### Wouldn't the second block would do fine on its own?
     if isinstance(data, contour):
       dtype2 = data.dtype
       if (dtype is None):
         dtype = dtype2
       if (dtype2 == dtype) and (not copy):
         return data
       return data.astype(dtype)

     if isinstance(data, numpy.ndarray):
       if dtype is None:
         intype = data.dtype
         intype = numpy.dtype(dtype)
       new = data.view(contour)
       if intype != data.dtype:
         return new.astype(intype)
       if copy: return new.copy()
       else: return new

     # now convert data to an array
     arr = numpy.array(data, dtype=dtype, copy=copy)

##### Do I need this if block?
     if not (arr.flags.fortran or arr.flags.contiguous):
       arr = arr.copy()

##### Do I need the fortran flag?
     ret = numpy.ndarray.__new__(subtype, arr.shape, arr.dtype,
                 buffer=arr, fortran=arr.flags.fortran)
     return ret

More information about the Numpy-discussion mailing list