What is the difference between __init__ and __call__?
Solution 1
The first is used to initialise newly created object, and receives arguments used to do that:
class Foo:
def __init__(self, a, b, c):
# ...
x = Foo(1, 2, 3) # __init__
The second implements function call operator.
class Foo:
def __call__(self, a, b, c):
# ...
x = Foo()
x(1, 2, 3) # __call__
Solution 2
Defining a custom __call__()
method in the meta-class allows the class's instance to be called as a function, not always modifying the instance itself.
In [1]: class A:
...: def __init__(self):
...: print "init"
...:
...: def __call__(self):
...: print "call"
...:
...:
In [2]: a = A()
init
In [3]: a()
call
Solution 3
In Python, functions are first-class objects, this means: function references can be passed in inputs to other functions and/or methods, and executed from inside them.
Instances of Classes (aka Objects), can be treated as if they were functions: pass them to other methods/functions and call them. In order to achieve this, the __call__
class function has to be specialized.
def __call__(self, [args ...])
It takes as an input a variable number of arguments. Assuming x
being an instance of the Class X
, x.__call__(1, 2)
is analogous to calling x(1,2)
or the instance itself as a function.
In Python, __init__()
is properly defined as Class Constructor (as well as __del__()
is the Class Destructor). Therefore, there is a net distinction between __init__()
and __call__()
: the first builds an instance of Class up, the second makes such instance callable as a function would be without impacting the lifecycle of the object itself (i.e. __call__
does not impact the construction/destruction lifecycle) but it can modify its internal state (as shown below).
Example.
class Stuff(object):
def __init__(self, x, y, range):
super(Stuff, self).__init__()
self.x = x
self.y = y
self.range = range
def __call__(self, x, y):
self.x = x
self.y = y
print '__call__ with (%d,%d)' % (self.x, self.y)
def __del__(self):
del self.x
del self.y
del self.range
>>> s = Stuff(1, 2, 3)
>>> s.x
1
>>> s(7, 8)
__call__ with (7,8)
>>> s.x
7
Solution 4
__call__
makes the instance of a class callable.
Why would it be required?
Technically __init__
is called once by __new__
when object is created, so that it can be initialized.
But there are many scenarios where you might want to redefine your object, say you are done with your object, and may find a need for a new object. With __call__
you can redefine the same object as if it were new.
This is just one case, there can be many more.
Solution 5
>>> class A:
... def __init__(self):
... print "From init ... "
...
>>> a = A()
From init ...
>>> a()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: A instance has no __call__ method
>>>
>>> class B:
... def __init__(self):
... print "From init ... "
... def __call__(self):
... print "From call ... "
...
>>> b = B()
From init ...
>>> b()
From call ...
>>>
sam
Updated on July 31, 2022Comments
-
sam over 1 year
I want to know the difference between
__init__
and__call__
methods.For example:
class test: def __init__(self): self.a = 10 def __call__(self): b = 20
-
pratikm over 9 yearsSo, the
__init__
method is used when the class is called to initialize the instance, while the__call__
method is called when the instance is called -
Murphy over 6 yearsThat seems correct, apparently instance variables can be modified during the life of an instance which can be beneficial in some cases.
-
Murphy over 6 yearsFor this specific case, should we not just create a new instance? Is this efficient in some way to modify and use the same instance.
-
Aquiles Carattino about 6 yearsComparing to Java is completely out of the scope of the question. In your example, you don't see any difference because it was poorly selected, the numbers are the same.
-
Don Slowik almost 6 yearsThis answer implies object instantiation (via _init_) presides over class call(via _call_). Reference?
-
user1270710 over 5 yearsinit is called when instantiating the class: myfoo = Foo(1,4,7.8) call is a template to call the already instantiated class to do something let's say class Foo:\ def __call__(self, zzz) Then, myfoo(12) calls the class to do what that class does.
-
Solomon Ucko over 5 yearsCould you please copy the output as text?
-
nealmcb about 5 yearsWhat is the point of this approach? Can you contrast it with a different approach?
-
Arindam Roychowdhury about 5 yearsJust a note: Since functions in general are callables, they always support the method call. So you can call function also like this: myFun.__call__(arg)
-
Ciasto piekarz almost 5 yearspassing an object to an initialised class object. So a callable object ?
-
Arthur over 4 years
__call__
not only allows an instance to be used as a function ... it defines the function body that's executed when an instance is used as a function. -
mrgloom over 4 yearsWhat is practical usage of
__call__
? -
dallonsi over 4 years
__init__
is not a constructor function but__new__
is.__init__
is called right after__new__
-
Prasad Raghavendra about 4 yearsI think this should be the accepted answer. It answers precisely.
-
Coffee_fan about 4 yearsI think
__new__
creates the class instance and receive a class as argument, whereas__init__
is the instance constructor which is why it receivesself
. An easy way to see this is in the calla = Foo(1,2,3)
the function that will receive the constructor arguments will be__init__
. -
cantordust about 4 yearsThe answer by Dmitriy Sintsov below raises a very important point, so I feel like I should draw attention to it here:
__call__
can return an arbitrary value, whereas__init__
must return None. -
Alex Povel about 4 yearsI understand the concept, but not the special feature of modifying its internal state. If we in the above code replace
def __call__
simply withdef update
, we give the class anupdate
method that does the same thing. It can now also modify the internal state, if called below ass.update(7, 8)
. So, is__call__
just syntactix sugar then? -
DannyMoshe almost 4 years@mrgloom, one way i have seen
__call__
used is with class-based decorators -
Chris Ivan over 3 yearsYes, pretty much. It's just a shortcut to invoking a method on the object without bothering to specify it. Other than that, it's like any other instance method. Interestingly, if you decorate it with @classmethod, it serves as both a classmethod and to make an instance callable. But since a classmethod can't take self, there is no state to pass around, and trying to call a class as a method calls
__init__
, so luckily it doesn't break the class construction. -
Safwan Samsudeen over 3 yearsDoes
__call__
not work when__init__
isn't there? -
Mahdi Amrollahi over 3 yearsWe typically use the class methods to perform a specific action, e.g. String.IndexOf(). When do we call an object?
-
Gergely M over 3 yearsIt's probably self-explanatory from the above comments, but I think also an important difference is
__init__
will run only once at instantiation although__call__
will run each time the Object is "called". -
user41855 almost 3 yearsThis one actually explains the significance of __call__()