Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using __add__ operator with multiple arguments in Python

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?

like image 750
smith1453 Avatar asked Oct 23 '17 09:10

smith1453


4 Answers

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)>
like image 191
Martijn Pieters Avatar answered Oct 07 '22 16:10

Martijn Pieters


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

like image 33
de1 Avatar answered Oct 07 '22 18:10

de1


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)
like image 43
mrCarnivore Avatar answered Oct 07 '22 16:10

mrCarnivore


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)>
like image 1
ThatOneAmazingPanda Avatar answered Oct 07 '22 17:10

ThatOneAmazingPanda