[Numpy-discussion] Overload binary operators with custom array type

Timothy Hochberg tim.hochberg at ieee.org
Fri Jan 12 14:37:48 EST 2007


On 1/12/07, Adam Jenkins <adam at thejenkins.org> wrote:
>
> I have written my own array class, let's call it "myarray", which behaves
> like a numpy.ndarray.  I would like to support binary operators with mixed
> operand types, i.e.:
>
> lhs + rhs
>
> where one of the operands is a myarray object, and the other is a
> numpy.ndarray object.
>
> The problem is that I want the operation in this case to be handled by my
> add method, not by numpy's add method.  If lhs is a myarray object, then
> this is no problem, since myarray.__add__(lhs, rhs) will be called.  However
> if lhs is a numpy array and rhs is a myarray, then numpy.ndarray.__add__(lhs,
> rhs) will be called, whereas what I would like to happen would be for
> myarray.__radd__(rhs, lhs) to be called.  Is there a way I can get numpy to
> do the latter?  Python will only call the rhs.__radd__ method if lhs.__add__
> returns NotImplemented, but as far as I can tell, the numpy.ndarray.__add__
> method never returns NotImplemented.
>
> It seems that for "lhs + rhs", where lhs is a numpy array, numpy does one
> of two things:
>
> 1. if rhs has an __array__ method, than it calls rsh.__array__(), which is
> expected to return a numpy.ndarray object.  Then it performs the binary
> operation with the result of __array__ for the rhs.
>
> 2. If rhs doesn't have an __array__ method, then it treats rhs as some
> kind of scalar, and tries to add each element of lhs to rhs.
>
> Under no circumstances does numpy just assume that it doesn't know what to
> do with rhs and return NotImplemented.  My question is, is there a way I can
> get the effect of having myarray.__radd__(rhs, lhs) in this case, or in some
> way get numpy to invoke my code to handle this operation rather than just
> assuming rhs is a scalar?
>
> As for why I don't just implement myarray.__array__(), the reason is
> because it would be expensive.  A myarray object doesn't actually contain
> the array data; rather it contains a handle referring to an array which
> resides in another process.  The server process which actually contains the
> arrays can even be on another machine.  So converting a myarray object to a
> numpy.ndarray involves transferring all the array data to the python
> process.  For various reasons, for my application it's preferable that I
> handle binary operators with mixed numpy/myarray operand types myself,
> rather than converting the myarray object to a numpy.ndarray.


You want __array_priority__; add an attribute __array_priority__ to your
array-like object and set it's value to, say, 10 and ndarrays will defer to
your object.


-- 
//=][=\\

tim.hochberg at ieee.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20070112/e9cdfe95/attachment.html>


More information about the NumPy-Discussion mailing list