[Numpy-discussion] Unexpected output using numpy.ndarray and__radd__

Tim Hochberg tim.hochberg at ieee.org
Mon Dec 18 08:05:34 EST 2006


Mark Hoffmann wrote:
> I appreciate the answer and the solution suggestion. I see that it is possible to make a work around by subclassing from ndarray. Still, in the "print a+c" statement, I don't understand why a.__add__(c) doesn't return NotImplemented (because ndarray shouldn't recognize the Cyclehist class) and directly call c.__radd__(a) implemented in my Cyclehist class. I tried the exactly same programme using Python 2.4.1 and Scipy 0.3.2 (based on numeric/numarray) and the result of the "print a+c" didn't get nested as I expect.
>
> Regards,
> Mark
>   
I'm not sure what this is doing -- it looks kind of bizzare -- however, 
you can fix this case without resorting to subclassing to ndarray. Just 
toss an '__array_priority__ = 10' up at the top of the class definition 
and it will use your __methods__ in preference to the ndarrays. I don't 
have time to look into this further right now unfortunately.

-tim


> -----Original Message-----
> From: numpy-discussion-bounces at scipy.org [mailto:numpy-discussion-bounces at scipy.org] On Behalf Of Stefan van der Walt
> Sent: 18. december 2006 10:36
> To: Discussion of Numerical Python
> Subject: Re: [Numpy-discussion] Unexpected output using numpy.ndarray and__radd__
>
> 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.
>
> Cheers
> Stéfan
> _______________________________________________
> Numpy-discussion mailing list
> Numpy-discussion at scipy.org
> http://projects.scipy.org/mailman/listinfo/numpy-discussion
> _______________________________________________
> Numpy-discussion mailing list
> Numpy-discussion at scipy.org
> http://projects.scipy.org/mailman/listinfo/numpy-discussion
>
>
>   





More information about the NumPy-Discussion mailing list