-1

I would like to implement class 'Add' such that return the sum of the arguments passed in a separate set of parentheses using call method and inheritance in python. for example:

>>>Add(10)
10
>>>Add(10)(11)
21
>>>Add(10)(11)(12)
33

I tried this piece of code do not receive the expected result.

class Add():
    def __init__(self, a):
        self.a = a
    def __call__(self, number):
        print(self.a + number)

>>>Add(10)
10
>>>Add(10)(11)
21

but for the third time( Add(10)(11)(12) ) I received the error 'int object is not callable.'

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119

1 Answers1

0

UPDATE:

As per @jsbueno's suggestion of inheriting int will get you what is needed.

class Add(int):
    def __init__(self, a):
        self.a = a
    def __call__(self, number):
        self.a += number # Store the result of your call.
        return self # return the instance back so that you can call it again and again.

This would let you use Add objects just like any other int objects.

>>> Add(10)(11) + Add(12)(13) # Returns 46

I am surprised with the error message you got : int object is not callable. One would expect you would get 'NoneType' object is not callable. At least that's what I got when I ran your code.

To achieve what you want to achieve, you need to return the instance back to the call-site, so that you can __call__ it again.

I would suggesting modifying your code like so:

class Add():
    def __init__(self, a):
        self.a = a
    def __call__(self, number):
        self.a += number # Store the result of your call.
        return self # return the instance back so that you can call it again and again.

You can then use it like:

Add(10)(11)(12) # Returns a instance of Add class.
Add(10)(11)(12).a # fetches the result of your calls.

Now this would change your original instance of Add(10). If that is not something you would want, you would replace your __call__ method with:

def __call__(self, number):
    result = self.a + number
    return Add(result)

This way, the base Add instance never really changes.

base = Add(10)
base.a # Would be 10
new_inst = base(11)(12)
new_inst.a # Would be 33
base.a # Would still be 10
  • thanks a lot. how can I receive the result without the attribute 'a' (exactly the same output I mentioned in the question) – Mohammad Ali Soltan Hosseini May 01 '23 at 17:21
  • I am not aware of any constructs in python that can help you achive both (chaining of calls and getting value directly) at the same time. You could probably implement `__int__` and `__float__` to return `self.a` and wrap the `Add(10)(11)(12)` in an `int()` or `float()` call get the value directly post chaining. – amd.srinivas May 01 '23 at 17:43
  • Actually, I think that jsut inheriting from `int` and and adding the `__call__` method, as in this answer, shoud do what the O.P. wants. @amd.srinivas - can you give it a try and add the result to your answer? – jsbueno May 04 '23 at 21:08