Using __add__ operator with multiple arguments in Python
Solution 1
No, you can't use multiple arguments. Python executes each +
operator separately, the two +
operators are distinct expressions.
For your example, object + 1 + 2
really is (object + 1) + 2
. If (object + 1)
produces an object that has an __add__
method, then Python will call that method for the second operator.
You could, for example, return another instance of A
here:
>>> class A:
... def __init__(self, val):
... self.val = val
... def __repr__(self):
... return f'<A({self.val})>'
... def __add__(self, other):
... print(f'Summing {self} + {other}')
... return A(self.val + other)
...
>>> A(42) + 10
Summing A(42) + 10
<A(52)>
>>> A(42) + 10 + 100
Summing A(42) + 10
Summing A(52) + 100
<A(152)>
Solution 2
You would want your return value to be an object itself, that also supports the add operation, e.g.:
class A:
def __init__(self, value=0):
self.value = value
def __add__(self, b):
return A(self.value + b)
def __str__(self):
return str(self.value)
a = A()
print(a + 1 + 2)
Output:
3
Solution 3
It perfectly works even with multiple values since each add only adds two values (see the multiple + signs when you ad multiple values):
class A:
def __init__(self, value):
self.a = value
def __add__(self, another_value):
return self.a + another_value
a = A(1)
print(a+1+1)
Solution 4
you could always just do this:
>>> class A:
... def __init__(self, val):
... self.val = val
... def __repr__(self):
... return f'<A({self.val})>'
... def __add__(self, other):
... print(f'Summing {self} + {other}')
... return A(self.val + other)
...
>>> A(42) + 10
Summing A(42) + 10
<A(52)>
>>> A(42) + 10 + 100
Summing A(42) + 10
Summing A(52) + 100
<A(152)>>>> class A:
... def __init__(self, val):
... self.val = val
... def __repr__(self):
... return f'<A({self.val})>'
... def __add__(self, other):
... print(f'Summing {self} + {other}')
... return A(self.val + other)
...
>>> A(42) + 10
Summing A(42) + 10
<A(52)>
>>> A(42) + 10 + 100
Summing A(42) + 10
Summing A(52) + 100
<A(152)>
smith1453
Updated on July 05, 2022Comments
-
smith1453 almost 2 years
I am trying to add a class object with a number, but I'm confused on how to go about adding a class object with two numbers. For example, this is my hypothetical add class method:
class A: def __add__(self, b): return something
I know how to add this so far:
a = A() print(a + 1)
But, what if I want to add it like this?
a = A() print(a + 1 + 2)
Should I use *args for the add class method?
-
de1 over 6 yearsIn this case the last add operation is not handled by the A class anymore but is a simple addition of 2 (returned by A.__add__) and 1.
-
N M over 6 yearsShouldn't an implemetation of radd also be added here? Also, in the case of 1 + 2 + 3, is the implementation (1.__add__(2)).__add__(3) or 1.__add__(2.__add__(3))?
-
mrCarnivore over 6 yearsYes you are right, but since 1 and 2 are numbers this is what should happen. If the author wanted to add two class instances then the example would not have been a+1 but a+b (a and b being instances of A)...
-
Martijn Pieters over 6 years@NM: That's not a requirement, not to answer the question at any rate.
-
Martijn Pieters over 6 years@NM: and
__radd__
is only going to be called if the LHS refused to handle the operation or if the RHS is a subclass of the LHS type.1 + 2 + 3
is(1).__add__(2).__add__(3)
. -
Martijn Pieters over 6 years@NM: to word it differently, for
LHS + RHS
, fornot issubclass(type(RHS), type(LHS))
,LHS.__add__(RHS)
is called first, and if that doesn't exist or returnsNotImplemented
only then isRHS.__radd__(LHS)
tried. The subclass exception is there to make it possible to subclass existing types and 'capture' the operator hook. -
ThatOneAmazingPanda over 3 yearsdoes this help?