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 likemyobj >4can work as you want and yield some result. This is >becausemyobj 4is interpreted asmyobj.__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 myobjwhich 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 valueNotImplemented. (The interpreter recognizes this special value coming from__add__and raises aTypeErrorexception 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 4was valid but4 myobjwas invalid. That's arbitrary and restrictive — addition is supposed to be commutative.Enter
__radd__. Python will first try(4).__add__(myobj), and if that returnsNotImplementedPython will check if the right-hand operand implements__radd__, and if it does, it will callmyobj.__radd__(4)rather than raising aTypeError.
