how to make an instance of a class callable for multiple times using multiple sets of parentheses in one line

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.'

Upvotes: -1

Views: 367

Answers (1)

amd.srinivas
amd.srinivas

Reputation: 46

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

Upvotes: 0

Related Questions