Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
__call__ in Python
Python __call__ Method
In Python, everything is treated as an object, including integers, strings, classes, and even functions. It provides a special method named __call__ that allows an instance of a class (i.e. object) to behave like a function (i.e. we can call/invoke it).
When we define the __call__ method inside a class, we can call its instance (object) using parentheses, just like a regular function.
Syntax
Following is the syntax to use the __call__ method inside a class ?
class MyClass:
def __call__(self, *args, **kwargs):
# Implementation of the method
Parameters
Following are the parameters of the __call__ method ?
- *args ? It accepts any number of positional arguments passed while calling the object.
- **kwargs ? It accepts any number of keyword arguments passed while calling the object.
Making an Object Work Like a Function Using __call__
Sometimes you may want to treat an object like a regular function. By defining the __call__ method inside a class, you can use the object itself with parentheses and pass arguments to it just like a function.
Example
In this example, we define a class CallableObject with a __call__ method that adds two numbers. When we use addition() with arguments, it behaves like a function call and returns the sum ?
# A simple class that behaves like a function
class CallableObject:
def __call__(self, x, y):
# return sum of x and y
return x + y
# Create an instance of the class
addition = CallableObject()
# Call the object like a function with arguments
result = addition(3, 4)
print(result)
Following is the output obtained ?
7
Building Function-like Objects Using __call__
If you are building an object that behaves like a mathematical function, such as a polynomial, the __call__ method allows you to calculate the result when the object is given an input.
We can use the internal data (like coefficients of the polynomial) inside the method to perform the necessary calculations, just like how a real mathematical function works.
Example
In this example, we define a class Polynomial that stores coefficients of a polynomial. The __call__ method uses these coefficients to calculate the result. When we use quadratic with an input value, it behaves like a function call and returns the result of the polynomial expression ?
# A class that represents a polynomial function
class Polynomial:
def __init__(self, coefficients):
# store the coefficient's list
self.coefficients = coefficients
def __call__(self, x):
# Calculate sum of coefficient * x^power for each term
return sum(coefficient * x**power for power, coefficient in enumerate(self.coefficients))
# Create a quadratic polynomial: x^2 - 2x + 1
quadratic = Polynomial([1, -2, 1])
# Evaluate the polynomial at x = 3
result = quadratic(3)
print(result)
We get the output as shown below ?
4
Using __call__ to Create a Decorator
We can also use the __call__ method to create a class-based decorator, which means using a class to add extra behaviour around a function.
In this case, the object stores a function and then wraps it using the __call__ method. When the decorated function is called, the object runs additional logic like measuring execution time before and after calling the actual function, all without changing how the function is called in the code.
Example
In this example, we define a class-based decorator TimingDecorator that wraps a function and uses the __call__ method to measure how long the function takes to run. When we use slow_function with arguments, it behaves like a function call and also prints the execution time ?
# A class-based decorator to measure function execution time
class TimingDecorator:
def __init__(self, function):
# store the function that needs to be decorated
self.function = function
def __call__(self, *args, **kwargs):
import time
# Record the start time
start_time = time.time()
# call the original function
result = self.function(*args, **kwargs)
# Record the end time
end_time = time.time()
# Print how long the function took to run
print(f"Execution time: {end_time - start_time:.4f} seconds")
return result # return the function result
# Use the class as a decorator for a slow function
@TimingDecorator
def slow_function(x):
import time
# Pause the program for x seconds
time.sleep(x)
return f"Finished sleeping for {x} seconds"
# Call the decorated function
result = slow_function(2)
print(result)
After executing the above code, we get the following output ?
Execution time: 2.0021 seconds Finished sleeping for 2 seconds
Conclusion
The __call__ method allows you to treat objects like functions. It is helpful when creating decorators, function wrappers, or custom callable objects. When used properly, it makes your Python code more organized especially in object-oriented programs.