I have a custom class implementing __add__ and __radd__ as
import numpy
class Foo(object):
def __init__(self, val):
self.val = val
def __add__(self, other):
print('__add__')
print('type self = %s' % type(self))
print('type other = %s' % type(other))
return self.val + other
def __radd__(self, other):
print('__radd__')
print('type self = %s' % type(self))
print('type other = %s' % type(other))
return other + self.val
I first test __add__
r1 = Foo(numpy.arange(3)) + numpy.arange(3,6)
print('type results = %s' % type(r1))
print('result = {}'.format(r1))
and it leads to the expected result
>>> __add__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'numpy.ndarray'>
>>> type results = <type 'numpy.ndarray'>
>>> result = [3 5 7]
However, testing __radd__
r2 = numpy.arange(3) + Foo(numpy.arange(3,6))
print('type results = %s' % type(r2))
print('result = {}'.format(r2))
I get
>>> __radd__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'int'>
>>> __radd__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'int'>
>>> __radd__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'int'>
>>> type results = <type 'numpy.ndarray'>
>>> result = [array([3, 4, 5]) array([4, 5, 6]) array([5, 6, 7])]
This doesn't make any sense to me. Does NumPy overload __add__ for arbitrary objects, which then takes priority over my __radd__? If yes, why would they do such a thing? Additionally, how can I avoid this, I really want to be able to add my custom class with a NumPy array to the left. Thanks.
numpyarrays is a bit tricky, there is a lot of underlying machinery. I believenumpyprovides mixins that let you do this relatively painlessly. I might be able to look into it later if no one else has the time. You can read more about it here__numpy_ufunc__ = None(__array_ufunc__ = Nonefor NumPy 13.0+) in my class, I get the result that I wanted.ufuncsAre vectorized functions.