[Numpy-discussion] Unexpected output using numpy.ndarray and __radd__

Stefan van der Walt stefan at sun.ac.za
Mon Dec 18 03:35:57 CST 2006

Hi Mark

On Mon, Dec 18, 2006 at 08:30:20AM +0100, Mark Hoffmann wrote:
> The following issue has puzzled me for a while. I want to add a numpy.ndarray
> and an instance of my own class. I define this operation by implementing the
> methods __add__ and __radd__. My programme (including output) looks like:
> #!/usr/local/bin/python
> import numpy
> class Cyclehist:
>     def __init__(self,vals):
>         self.valuearray = numpy.array(vals)
>     def __str__(self):
>         return 'Cyclehist object: valuearray = '+str(self.valuearray)
>     def __add__(self,other):
>         print "__add__ : ",self,other
>         return self.valuearray + other
>     def __radd__(self,other):
>         print "__radd__ : ",self,other
>         return other + self.valuearray
> c = Cyclehist([1.0,-21.2,3.2])
> a = numpy.array([-1.0,2.2,-2.2])
> print c + a
> print a + c

In the first instance, c.__add__(a) is called, which works fine.  In
the second, a.__add__(c) is executed, which is your problem, since you
rather want c.__radd__(a) to be executed.  A documentation snippets:

"""For instance, to evaluate the expression x-y, where y is an
instance of a class that has an __rsub__() method, y.__rsub__(x) is
called if x.__sub__(y) returns NotImplemented.

Note: If the right operand's type is a subclass of the left operand's
type and that subclass provides the reflected method for the
operation, this method will be called before the left operand's
non-reflected method. This behavior allows subclasses to override
their ancestors' operations."""

Since a.__add__ does not return NotImplemented, c.__radd__ is not
called where you expect it to be.  I am not sure why broadcasting
takes place here, maybe someone else on the list can elaborate.

To solve your problem, you may want to look into subclassing ndarrays,
as described at http://www.scipy.org/Subclasses.


More information about the Numpy-discussion mailing list