2

I have a class defined as

class MyClass(object):

    def __init__(self, value=0):
        self.value = value

    def __add__(self,other):
        return MyClass(self.value + other.value)

    __radd__ = __add__

I would like simply to apply the sum function to them like this:

a=MyClass(value=1)
b=MyClass(value=2)

c=[a,b]
print sum(c)  # should return a MyClass instance with value 3

as was suggested in this post. However, an exception is raised:

     15 
     16 c=[a,b]
---> 17 print sum(c)

TypeError: unsupported operand type(s) for +: 'int' and 'MyClass'

I don't understand why the sum function wants to add two different types.

Community
  • 1
  • 1
ldocao
  • 129
  • 2
  • 12

2 Answers2

4

sum needs somewhere to start; by default, it starts at 0. So the first operation it attempts is 0 + MyClass(value=1), which you haven't told it how to do!

You therefore have two choices, either:

  1. Specify the start (e.g. sum(c, MyClass())); or
  2. Tell MyClass how to deal with adding integers to instances.

The latter could look like:

class MyClass(object):

    ...

    def __add__(self, other):
        try:
            return MyClass(self.value + other.value)  # handle things with value attributes
        except AttributeError:
            return MyClass(self.value + other)  # but also things without

    ...

which lets you skip the explicit start:

>>> sum([MyClass(1), MyClass(2)]).value
3
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
2

Because sum(iterable[, start]) sums start and the items of an iterable from left to right and returns the total. start defaults to 0.

You can modify the class by

class MyClass(object):

    def __init__(self, value=0):
        self.value = value

    def __add__(self, other):
        if (isinstance(other, MyClass)):
            return MyClass(other.value + self.value)
        else:
            return MyClass(other + self.value)

    __radd__ = __add__
yangjie
  • 6,619
  • 1
  • 33
  • 40
  • 1
    I see, thanks ! I need then to initialize my sum by setting for example: sum(c,MyClass(0)) – ldocao Jul 01 '15 at 10:01
  • @LongDoCao that is one way of solving the problem, yes. Should `MyClass` instances be able to be added to integers? – jonrsharpe Jul 01 '15 at 10:18
  • @jonrsharpe : not in my case, but this is good to know anyway. Thanks. – ldocao Jul 01 '15 at 13:53
  • @jonrsharpe yup, sorry about that, I accepted the other answer because it just came before yours, and helped me understand what to do. I changed the accepted answer. cheers. – ldocao Jul 01 '15 at 15:27