What is the difference between __init__ and __call__?

309,998

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 ... 
>>> 
Share:
309,998
sam
Author by

sam

Updated on July 31, 2022

Comments

  • sam
    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
    pratikm over 9 years
    So, 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
    Murphy over 6 years
    That seems correct, apparently instance variables can be modified during the life of an instance which can be beneficial in some cases.
  • Murphy
    Murphy over 6 years
    For 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
    Aquiles Carattino about 6 years
    Comparing 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
    Don Slowik almost 6 years
    This answer implies object instantiation (via _init_) presides over class call(via _call_). Reference?
  • user1270710
    user1270710 over 5 years
    init 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
    Solomon Ucko over 5 years
    Could you please copy the output as text?
  • nealmcb
    nealmcb about 5 years
    What is the point of this approach? Can you contrast it with a different approach?
  • Arindam Roychowdhury
    Arindam Roychowdhury about 5 years
    Just 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
    Ciasto piekarz almost 5 years
    passing an object to an initialised class object. So a callable object ?
  • Arthur
    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
    mrgloom over 4 years
    What is practical usage of __call__?
  • dallonsi
    dallonsi over 4 years
    __init__ is not a constructor function but __new__ is. __init__ is called right after __new__
  • Prasad Raghavendra
    Prasad Raghavendra about 4 years
    I think this should be the accepted answer. It answers precisely.
  • Coffee_fan
    Coffee_fan about 4 years
    I think __new__ creates the class instance and receive a class as argument, whereas __init__ is the instance constructor which is why it receives self. An easy way to see this is in the call a = Foo(1,2,3) the function that will receive the constructor arguments will be __init__.
  • cantordust
    cantordust about 4 years
    The 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
    Alex Povel about 4 years
    I understand the concept, but not the special feature of modifying its internal state. If we in the above code replace def __call__ simply with def update, we give the class an update method that does the same thing. It can now also modify the internal state, if called below as s.update(7, 8). So, is __call__ just syntactix sugar then?
  • DannyMoshe
    DannyMoshe almost 4 years
    @mrgloom, one way i have seen __call__ used is with class-based decorators
  • Chris Ivan
    Chris Ivan over 3 years
    Yes, 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
    Safwan Samsudeen over 3 years
    Does __call__ not work when __init__ isn't there?
  • Mahdi Amrollahi
    Mahdi Amrollahi over 3 years
    We typically use the class methods to perform a specific action, e.g. String.IndexOf(). When do we call an object?
  • Gergely M
    Gergely M over 3 years
    It'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
    user41855 almost 3 years
    This one actually explains the significance of __call__()