Each Answer to this Q is separated by one/two green lines.

I am trying to understand how `__add__`

works:

```
class MyNum:
def __init__(self,num):
self.num=num
def __add__(self,other):
return MyNum(self.num+other.num)
def __str__(self):
return str(self.num)
```

If I put them in a list

```
d=[MyNum(i) for i in range(10)]
```

this works

```
t=MyNum(0)
for n in d:
t=t+n
print t
```

But this does not:

```
print sum(d)
TypeError: unsupported operand type(s) for +: 'int' and 'instance'
```

What am I doing wrong? How can I get the **sum()** to work?

My problem is how to use the sum on a list of objects that support the `__add__`

, need to keep it as generic as possible.

You need to define `__radd__`

as well to get this to work.

`__radd__`

is *reverse add*. When Python tries to evaluate `x + y`

it first attempts to call `x.__add__(y)`

. If this fails then it falls back to `y.__radd__(x)`

.

This allows you to override addition by only touching one class. Consider for example how Python would have to evaluate `0 + x`

. A call to `0.__add__(x)`

is attempted but `int`

knows nothing about your class. You can’t very well change the `__add__`

method in `int`

, hence the need for `__radd__`

. I suppose it is a form of dependency inversion.

As Steven pointed out, `sum`

operates in place, but starts from 0. So the very first addition is the only one that would need to use `__radd__`

. As a nice exercise you could check that this was the case!

```
>>> help(sum)
Help on built-in function sum in module __builtin__:
sum(...)
sum(sequence[, start]) -> value
Returns the sum of a sequence of numbers (NOT strings) plus the value
of parameter 'start' (which defaults to 0). When the sequence is
empty, returns start.
```

In other words, provide a start value:

```
sum(d, MyNum(0))
```

**Edit pasted from my below comment:**

`sum`

works with a default start value of the integer zero. Your `MyNum`

class as written does not know how to add itself to integers. To solve this you have two options. Either you can provide a start value to `sum`

that has the same type as you class, or you can implement `__radd__`

, *which Python calls when adding values of differing types* (such as when the first value in `d`

is added to the default start value of zero).

```
class MyNum:
def __init__(self,num):
self.num=num
def __add__(self,other):
return self.num += other.num
def __str__(self):
return str(self.num)
one = MyNum(1)
two = MyNum(2)
one + two
print(two.num)
```

Another option is reduce (functools.reduce in Python 3.x).

```
from functools import reduce
from operators import add
d=[MyNum(i) for i in range(10)]
my_sum = reduce(add,d)
```

I oppose relaying on sum() with a start point, the loop hole exposed below,

```
In [51]: x = sum(d, MyNum(2))
In [52]: x.num
Out[52]: 47
```

Wondering why you got 47 while you are expecting like

…start from 2nd of MyNum() while leaving first and add them till end, so the expected result = 44 (sum(range(2,10))

The truth here is that 2 is not kept as start object/position but instead treated as an addition to the result

sum(range(10)) + 2

oops, link broken !!!!!!

Use **radd**

Here below the correct code. Also note the below

**Python calls __radd__ only when the object on the right side of the + is your class instance**

eg: 2 + obj1

```
#!/usr/bin/env python
class MyNum:
def __init__(self,num):
self.num=num
def __add__(self,other):
return MyNum(self.num+other.num)
def __radd__(self,other):
return MyNum(self.num+other)
def __str__(self):
return str(self.num)
d=[MyNum(i) for i in range(10)]
print sum(d) ## Prints 45
d=[MyNum(i) for i in range(2, 10)]
print sum(d) ## Prints 44
print sum(d,MyNum(2)) ## Prints 46 - adding 2 to the last value (44+2)
```