What is the difference between __init__ and __call__ in Python?

In Python, __init__ and __call__ are special methods which are indicated by double underscores as their names. They are important in controlling the operations of classes and instances in the Python programming language. These dunderOften called dunder methods due to their double underscores at the beginning and end. methods are basic to Python’s object-oriented programming and have specific uses that enable different programming approaches. Now let’s discuss each method in detail and highlight why they were developed, what they can do, and where they can be used.

The __init__ method

The __init__ method acts as a constructor in a Python class and gets called when a new instance of a class is created. Its main role is to set the initial state or characteristics of the new object right after object creation. In general, this method is used to set the values of the object’s properties; however, it can also carry out any other necessary initialization for the object.

As __init__ is intended to be the first method invoked when an instance of the class is created, it cannot return any value, as it returns None inherently. This restriction is necessary because the method is designed to set up the object’s initial state rather than to compute a return value. The __init__ method is called automatically by Python at the time of object instance creation. This automatic execution ensures that the object is immediately ready to run with all the attributes and configurations needed for its proper functioning.

Example

Here’s an example of the Recipe class that utilizes the __init__ method to create a new instance.

class Recipe:
def __init__(self, name, ingredients, cuisine):
self.name = name
self.ingredients = ingredients
self.cuisine = cuisine
def display_recipe(self):
ingredients_list = ", ".join(self.ingredients)
return f"The recipe for {self.name} includes the following ingredients: {ingredients_list}. This is a traditional dish from {self.cuisine} cuisine."
# Create an instance of Recipe
pasta_dish = Recipe("Spaghetti Carbonara", ["spaghetti", "eggs", "pecorino cheese", "guanciale"], "Italian")
print(pasta_dish.display_recipe())

Explanation

  • Lines 1–5: The Recipe class is defined with three attributes in its constructor (__init__): name, ingredients, and cuisine.

  • Lines 7–9: The display_recipe() method formats and displays the recipe details, including a list of ingredients and the cuisine type.

  • Line 12: An instance of the Recipe class is created representing “Spaghetti Carbonara” with a list of its ingredients identifying it as an Italian dish.

  • Line 13: When display_recipe() is called, it returns a formatted string detailing the recipe and its cultural context.

The __call__ method

The __call__ method allows an instance to be invoked as a function, something which is not normally possible in objects unless this method is defined. Through __call__, we can provide the objects of a class with the ability to act like functions, store data, and also perform actions using the data contained within the object. This can be very powerful in designs where objects need to behave like functions or when the whole class is used to represent a certain operation.

The __call__ method has several important features. Its main use is to make instances of a class act like functions; this increases its versatility and utility over and above the standard object-related behaviors. As for the return type of the method, it can return anything a normal function can, which has unlimited potential when it comes to results. Lastly, for invocation, it calls for the instance to be invoked as a function and this implies the user has to initiate the method using the instance. It allows for more dynamic control of objects within a programming environment.

Example

Here’s an example of a Multiplier class that utilizes the __call__ method, allowing its instances to function as callable objects that multiply a given number by a predefined factor.

class Multiplier:
def __init__(self, factor):
self.factor = factor
def __call__(self, x):
return self.factor * x
# Create a multiplier instance
multiplier3 = Multiplier(3)
# Use the instance as a callable
print(multiplier3(10)) # Outputs should be 30, as 3 * 10 = 30

Explanation

  • Lines 1–3: The Multiplier class is defined, including a constructor (__init__) that initializes each instance with a specific multiplication factor.

  • Line 5–6: The __call__ method is defined within the Multiplier class. This special method allows an instance of the class to be called as if it were a function, using the factor stored during initialization to multiply any given number.

  • Line 9: An instance of the Multiplier class, multiplier3, is created and initialized with a factor of 3. This means multiplier3 is configured to triple any number it processes.

  • Line 12: The instance multiplier3 is used as a callable to multiply the number 10 by the stored factor, 3. The operation results in 30, demonstrating how the instance behaves like a function.

Comparison of __init__ and __call__

Here’s a table summarizing the key differences between __init__ and __call__ in Python:

Aspect

The __init__ Method

The __call__ Method

Core functionality

Used exclusively for setting up new objects, ensuring they start with a defined state.

Gives objects callable functionality, allowing them to act and execute as if they were functions.

Usage scenarios

Used to initialize attributes or perform setup activities when an instance is created.

Used when the instance needs to perform operations in a function-like manner, possibly depending on its internal state.

Invocation details

Runs automatically and only once per instance creation.

Can be invoked any number of times and must be triggered explicitly, similar to calling a regular function.

Conclusion

In conclusion, Python’s __init__ and __call__ functions demonstrate the language’s tremendous object-oriented capabilities. The __init__ method initializes new objects that are immediately given all of the necessary features, whereas __call__ converts these objects into callable entities that can perform activities on the fly. This not only improves Python’s flexibility but also expands the possibilities for developing unique programming concepts.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved