13

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?

4 Answers 4

20

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)>
Sign up to request clarification or add additional context in comments.

4 Comments

Shouldn'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))?
@NM: That's not a requirement, not to answer the question at any rate.
@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).
@NM: to word it differently, for LHS + RHS, for not issubclass(type(RHS), type(LHS)), LHS.__add__(RHS) is called first, and if that doesn't exist or returns NotImplemented only then is RHS.__radd__(LHS) tried. The subclass exception is there to make it possible to subclass existing types and 'capture' the operator hook.
5

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

Comments

2

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)

2 Comments

In 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.
Yes 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)...
2

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)>

1 Comment

does this help?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.