In Python, everything, including a function, is an object, and it allows you to make your objects behave like functions. This can be done by implementing the __call__() method. When you define a __call__() method in your class, you can “call” an instance of that class as if it were a regular function. This makes your object behave like a function, giving it a second, callable identity. In this blog, you will understand the call() method in Python, including its syntax and detailed examples.
Table of contents:
What is a Callable Object in Python?
In simple terms, a callable is an object that can be used like a function by adding parentheses (). In Python, functions are naturally callable, but you can also make custom objects callable by implementing the __call__() method
Example:
Output:
Explanation: Here, len is already a function, which is why we can call it. A string like “hello” is not callable because you can’t use parentheses as you would with a function. When you add a __call__() method to a class, then instances of that class become callable too.
How does the __call__() Method Work in Python
When you call an instance of the class(similar to how you would call a function), Python checks if that instance’s class has a method named __call__(). If it does, then Python proceeds to run that method. So when you write something like obj(), Python runs obj.__call__() behind the scenes. This is one of Python’s ‘magic’ methods, others include __init__(), __str__(), and more.
Boost your tech career with Python – Sign up now!
Practical projects, job-ready skills, and expert guidance.
Syntax of the __call__() Method in Python
Here’s how you write the __call__() method inside your class. You can also pass arguments to it just like a normal function.
Syntax:
def __call__(self, arg1, arg2, ...):
- self: Refers to the instance of the class.
- arg1, arg2, …: These represent optional arguments that can be passed when the object is called like a function.
You can define __call__() with or without arguments, depending on the behaviour you want your object to perform when called.
Creating a Callable Class Using __call__() in Python
A callable class is one where instances can be called like functions. By defining the __call__() method, you give the class instance a function-like behavior when using parentheses.
Example:
Output:
Explanation: Here, the Greeter class has a __call__() method that takes one argument, name. When you run greet(“Kayraa”), Python does greet.__call__(“Kayraa”), and prints the greeting.
Using __call__() in a Class in Python
The __call__() method allows objects of a class to be invoked as if they were regular functions. This is useful for designing flexible and reusable code, such as function wrappers or stateful behaviors. Below, we will create a class that adds two numbers using the __call__() method.
Example:
Output:
Explanation: Here, the Adder class has a __call__() method that takes two numbers and returns their sum. When you use add(22, 33), Python actually runs add.__call__(22, 33) and gives you the result 55.
Difference Between __call__() and a Regular Function Call in Python
Feature |
Regular Function Call |
Object with __call__() Method |
Defined using |
def keyword outside a class |
__call__() method inside a class |
Callable |
Yes, because you call it directly like func() |
Yes, only if __call__() is defined, allowing the object to be called like a function |
Usage |
You call it directly like func() |
You call the object like obj() |
Flexibility |
Used mostly for one specific task |
Can hold internal state and behaviour together |
Object-Oriented Programming Use |
Not tied to OOP |
Integrates well with OOP |
Example |
def greet(): return “Hi” |
class Greeter: def __call__(self): return “Hi” |
Why and When to Use the __call__() Method in Python
The __call__() method lets you use an object like a function by adding parentheses. This is helpful when:
- You want to wrap another function (like in decorators).
- The object needs to remember some data between calls.
- You want to perform math or repeat a calculation easily.
- You want your code to look cleaner, especially in things like machine learning or frameworks.
- You are building custom classes that act like functions.
- You want to control how the object behaves when it’s “called” with different inputs.
Get 100% Hike!
Master Most in Demand Skills Now!
Combining __call__() with Closures in Python
The use of closure in Python is defined as functions that return other functions and remember data. The __call__() method can achieve a similar result in a more structured and object-oriented way.
Example:
Output:
Explanation: In the first part, we are using a closure. The multiplier_closure() function returns another function that remembers the value of n. In the second part, we are using a class with the __call()__ method. This lets us use the object like a function. Both do the same job: multiply a number by 2.
Here, using the __call()__ method gives us more control. For example, we can later add features like printing logs, checking inputs, or changing the multiplier easily.
Using __call__() in Machine Learning
When we talk about machine learning libraries like TensorFlow and PyTorch, the model classes often define a __call__() method, which converts them into a function.
Example:
Output:
Explanation: Here, the SampleModel does the work of doubling the input. We called the model object directly using __call__() instead of a typical predict() method. This is quite similar to how deep learning frameworks operate.
Use Cases for Implementing __call__() in Python
The below section carries two sample use cases to implement the __call__() method in Python.
Use Case 1: Logger Object
Assume a logger class; You aim to log messages, but you want to configure the logger just once and then attempt to reuse it. What you can do here is implement __call__() method and turn your logger into a callable object.
Example:
Output:
Explanation: Here, you can see that the logger class used the __init__() method to store the prefix. Then the __call__() method takes a message and prints it with that prefix. Every moment that you call log(…), it starts to behave like a function, but also remembers the prefix set earlier.
Use Case 2: Building a Counter Object:
What if you want a counter that increases every time you call it? Here’s how you can do that using __call__().
Example:
Output:
Explanation: Here, this Counter object maintains state using self.count. Every time you call counter(), it runs the __call__() method and increases the internal count. This is helpful in situations like tracking operations, logging usage, or rate-limiting actions.
Best Practices for Using __call__() in Python
Here we have provided you with five best practices to follow when working with the __call__() method:
- Use the method only when its involvement makes sense: Try not to add __call__() just because you can. Use it only when calling the object improves clarity.
- Keep the code snippet simple: Avoid writing too much logic inside the method. The code should be easy to read and clean.
- Add docstrings if possible: Always comment or document your __call__() method to show what function it performs.
- Do not replace regular functions: Try using regular functions when object state is not needed.
- Use a reusable logic: This practice is great for encapsulating behaviour, especially if your object needs to perform actions repeatedly.
Start Your Python Journey – 100% Free
Learn the basics of Python through hands-on practice and projects.
Conclusion
By now, you should understand how the __call__() method allows your objects to behave like functions. You’ve explored its syntax and discovered practical use cases where it can be used. By learning how to use __call__(), you’ve added a powerful tool to your Python toolbox. The true strength of the __call__() method lies in its ability to combine behaviour with data, allowing objects to be more flexible and dynamic. This method is widely used in advanced Python frameworks like TensorFlow, where such flexibility is essential.
To take your skills to the next level, enrol in our Python Training Course and gain hands-on experience. Also, prepare for job interviews using Python Interview Questions, designed by industry experts.
__call__() Method in Python – FAQs
Q1. Is it possible to use __call__() without including arguments?
Yes, you can define __call__(self) without involving any parameters if your operation doesn’t need inputs.
Q2. Does using __call__() give us faster results than normal functions?
No, it is certainly not faster. It is mainly used for design purposes, not performance-oriented.
Q3. Can I override __call__() in a child class?
Yes, just define a new __call__() method in your subclass to change behavior.
Q4. Can I define multiple __call__() methods?
No, like any method, only one version can exist per class. Use default or keyword arguments for flexibility.
Q5. What happens if I call an object without __call__()?
You’ll get a TypeError saying the object is not callable.