Home > Net >  add more than two objects with __add__ function
add more than two objects with __add__ function

Time:08-14

I have a class it can successfully add two variables of object of class a

class a():
    def __add__(self, other):
        return self.val other.val
    def __init__(self,a):
        self.val=a
aa=a(22)
bb=a(11)
aa bb
33

But when I try to give it third object to add, it through error

cc=a(11)
aa bb cc
Traceback (most recent call last):
  File "<pyshell#43>", line 1, in <module>
    aa bb cc
TypeError: unsupported operand type(s) for  : 'int' and 'a'

It is because first two aa bb return int and its add function is design to add object addition Any one can suggest how I can add three objects

I find this link Using __add__ operator with multiple arguments in Python but it is working on one object and 2 integers. But I want to add three objects. and all these three combine and return integer

CodePudding user response:

__add__ must return an instance of a class, not int

class a():
    def __add__(self, other):
        return a(self.val   other.val)
    def __init__(self, a):
        self.val = a

CodePudding user response:

Here's an example of how __add__ and __radd__ should be implemented.

We have a class A that has an attribute n which is an integer. We want to be able to add classes of the same type and we also want to be able to add integer values. Therefore:

class A:
    def __init__(self, n):
        self._n = n
    @property
    def n(self):
        return self._n
    def __add__ (self, other):
        if isinstance(other, int):
            return A(self.n   other)
        assert isinstance(other, type(self))
        return A(self.n   other.n)
    def __radd__(self, other):
        assert isinstance(other, int)
        return A(self.n   other)
    def __str__(self):
        return f'{self.n}'
    def __repr__(self):
        return f'{self.n=}'

a = A(1)
b = A(2)
c = A(3)

print(10 a 10 b 10 c 10)

c  = 5
print(c)
print(c.n)

Output:

46
8
8

CodePudding user response:

you need to have a __radd__ method, this is because the __add__ method returns an int and the int.__add__ method cannot add with the a class.

The __radd__ will be something like this:

class a:
    def __init__(self,val):
        self.val = val
    def __add__(self,other):
        return self.val other.val
    def __radd__(self,other):
        return self.val other

Here is the functioning of the __radd__ method:

Suppose you are implementing a class that you want to act >like a number via operator overloading. So you implement >__add__ in your class, and now expressions like myobj >4 can work as you want and yield some result. This is >because myobj 4 is interpreted as myobj.__add__(4), >and your custom method can do whatever it means to add 4 to your custom class.

However, what about an expression like 4 myobj which is really (4).__add__(myobj)? The 4 is an instance of a Python built-in type and its __add__ method doesn't know anything about your new type, so it will return a special value NotImplemented. (The interpreter recognizes this special value coming from __add__ and raises a TypeError exception which kills your program, which is the behavior you'd actually see, rather than the special value being returned.)

It would suck for operator overloading if myobj 4 was valid but 4 myobj was invalid. That's arbitrary and restrictive — addition is supposed to be commutative.

Enter __radd__. Python will first try (4).__add__(myobj), and if that returns NotImplemented Python will check if the right-hand operand implements __radd__, and if it does, it will call myobj.__radd__(4) rather than raising a TypeError.

  • Related