How to overload __add__ method in a self made class to sum multiple objects of the class?

class MyClass:
    def __init__(self, value):
        self.value = value

    def __add__(self, other):
        if isinstance(other, MyClass):
            return self.value + other.value
        elif isinstance(other, int) or isinstance(other, float):
            return self.value + other
        else:
            raise TypeError("Unsupported operand type(s) for +")

# Creating objects of MyClass
obj1 = MyClass(10)
obj2 = MyClass(20)
obj3 = MyClass(30)

# Adding multiple objects using the + operator
result = obj1 + obj2 + obj3

print(result)  # Output: 60

I have received this solution from chat gpt but this does not work. I can’t sum more than 2 objects of my class. How can i solve this?;D (sorry for bad English)

Your __add__ currently returns an object of whatever type MyClass.value is. To be able to chain additions, the __add__ method should return a MyClass instance.

Or you might be able to add an __radd__ method, but not 100% sure about that.

Hi !

When adding two objects in Python, the order of the two objects around the + operator matters ! When you call obj1 + obj2 + obj3, obj1 + obj2 is first evaluated and returns an integer (30). Then, 30 + obj3 is evaluated, but the type of 30 (int) does not implement addition with objects of type MyClass, and you get an error.

If you now call obj1 + (obj2 + obj3), (obj2 + obj3) is first evaluated and returns an int (50). Then, obj1 + 50 is evaluated, and since the __add__ method of MyClass supports addition with objects of type int, you get the expected result 60 (try it !).

As @ajoino mentioned, the __radd__ method can solve your problem. Basically, in case the addition first fails (like in 30 + obj3), it will try the same operation with reversed operands (obj3 + 30). The following code works for me:


class Myclass:

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

    def __add__(self, other):
        if isinstance(other, Myclass):
            return self.value + other.value
        elif isinstance(other, int) or isinstance(other, float):
            return self.value + other
        else:
            raise TypeError("Unsupported operand type(s) for +")

    def __radd__(self, other):
      return self.__add__(other)


if __name__ == "__main__":

    obj1 = Myclass(10)
    obj2 = Myclass(20)
    obj3 = Myclass(30)

    result = obj1 + obj2 + obj3

    print(result)

As Antoine wrote - you should add an __radd__ method in order to be able to add numerical values to objects of MyClass. But as @ajoino wrote, you should also let your __add__ method return objects of MyClass; your initial problem was caused by not doing so. It’s formally possible to have the __add__ method return other types, but it will create a lot of confusion in using the addition operator (as you already noticed yourself).
So, you could change the method to this (or sth similar):

def __add__(self, other):
    if isinstance(other, MyClass):
        return MyClass(self.value + other.value)
    elif isinstance(other, int) or isinstance(other, float):
        return MyClass(self.value + other)
    else:
        raise TypeError("Unsupported operand type(s) for +")

If you implement those methods, it’s usually also good to implement __iadd__ in order to support +=.

For a more elaborate example, see: numbers — Numeric abstract base classes — Python 3.12.0 documentation.

3 Likes

Wow that’s great. I was just looking for such this answer:D. Thank you so much man.:slight_smile: