I want to create a class called Chain
.
I want to be able to call __init__
method multiple times.
For example:
>> Chain(1)
1
>> Chain(1)(2)
3
How can I do this in Python?
I want to create a class called Chain
.
I want to be able to call __init__
method multiple times.
For example:
>> Chain(1)
1
>> Chain(1)(2)
3
How can I do this in Python?
You just need a callable int
:
>>> class Chain(int):
... def __call__(self, other: int) -> Chain:
... return Chain(self + other)
...
>>> Chain(10) == 10
True
>>> Chain(1)(2)(3)
6
To do exactly what you have shown (the usefulness of which I question), you need to override __repr__
and define __call__
. For example,
class Chain:
def __init__(self, x):
self.x = x
def __repr__(self):
return repr(self.x)
def __call__(self, x):
return Chain(self.x + x)
Since __call__
returns a new instance of Chain
, you can chain calls indefinitely.
>>> Chain(1)
1
>>> Chain(1)(2)
3
>>> Chain(1)(2)(3)
6
Chain
itself will always return an instance of Chain
(unless you define Chain
using a metaclass other than the default of type
). Chain.__call__
is what allows you to call an instance of Chain
like a function, returning a function to allow the actual chain of calls to continue. __repr__
is used so that each attempt to "show" the instance produces the value of its attribute.
Does this answer your question?
class Chain:
def __init__(self, value):
self.value = value
def __call__(self, value):
return Chain(self.value + value)
one = Chain(1)
three = Chain(1)(2)
print(three.value)
Just to explain what __call__
does is:
call is method enables Python programmers to write classes where the instances behave like functions and can be called like a function.
As far as I know, you cannot implement multiple __inits__
since it's the function which initializes variables etc.
What you can do is implement the __call__
function, which is the one being called when you call an instance e.g
class MyClass:
def __init__(self,a):
self.a = a
print("Init")
def __call__(self,b):
print("call")
self.b=b
inst = MyClass(1) # "Init"
inst(2) #"call"