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 >4
can work as you want and yield some result. This is >becausemyobj 4
is 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 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 valueNotImplemented
. (The interpreter recognizes this special value coming from__add__
and raises aTypeError
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 but4 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 returnsNotImplemented
Python will check if the right-hand operand implements__radd__
, and if it does, it will callmyobj.__radd__(4)
rather than raising aTypeError
.