How to Create Callable Objects in Python Using __call__ Method
1. The Problem
I was reading through some Python library code when I encountered this confusing syntax:
multiplier = Multiplier(3)result = multiplier(5) # Wait, I'm calling an object instance like a function?print(result) # Output: 15At first, I thought maybe multiplier was somehow a function, not an instance. But no, Multiplier(3) clearly creates an object instance. So how can I call an instance like a function with multiplier(5)?
Then I saw an even more confusing pattern:
result = SomeClass()() # Double parentheses on a class?I was completely lost. In my mental model, you call functions with (), not object instances. What was going on here?
2. What I Initially Thought (Wrong!)
My first instinct was to assume this was some kind of Python magic I didn’t understand. I had a few wrong theories:
Theory 1: Maybe multiplier is actually a function reference?
# I thought maybe it was like this:multiplier = some_function # Reference to a functionresult = multiplier(5) # This makes senseBut that didn’t explain the Multiplier(3) part clearly creating an instance.
Theory 2: Maybe there’s some inheritance from a callable base class?
# I thought maybe:class Multiplier(SomeCallableBaseClass): # Does this exist? ...I was overcomplicating things. The real answer is much simpler.
3. Discovering the __call__ Method
After some research, I discovered that Python has a special method called __call__ that makes object instances callable. This was my “aha” moment.
Let me show you the simplest example:
class Greeter: def __init__(self, name): self.name = name
def __call__(self, greeting): """This method is called when you use () on an instance""" return f"{greeting}, {self.name}!"
# Create an instancegreeter = Greeter("Alice")
# Now call the instance like a function!result = greeter("Hello")print(result) # Output: Hello, Alice!When I ran this code:
Hello, Alice!So the __call__ method is what makes instances callable. When you write greeter("Hello"), Python is actually calling greeter.__call__("Hello").
4. Understanding What “Callable” Means
Before diving deeper, let me clarify what “callable” means in Python. A callable is anything you can invoke with the () syntax.
# Check what's callable using the built-in callable() function
# Functions are callableprint(callable(len)) # Trueprint(callable(print)) # True
# Classes are callable (they create instances)print(callable(list)) # Trueprint(callable(dict)) # True
# Most objects are NOT callable by defaultprint(callable("hello")) # Falseprint(callable(42)) # Falseprint(callable([1, 2, 3])) # False
# But with __call__, instances become callableclass MyCallable: def __call__(self): return "I'm callable!"
obj = MyCallable()print(callable(obj)) # TrueOutput:
TrueTrueTrueTrueFalseFalseFalseTrueThis helped me understand: Python doesn’t care what something is, only what it can do. This is duck typing in action - if it has __call__, it’s callable.
5. Practical Examples
Once I understood the basics, I started seeing practical uses everywhere. Here are the patterns I found most useful:
5.1 Stateful Functions
This is perhaps the most common use case - functions that remember state between calls:
class Counter: """A counter that maintains state across calls"""
def __init__(self, start=0): self.count = start
def __call__(self, increment=1): self.count += increment return self.count
# Create independent countersmy_counter = Counter(10)your_counter = Counter(100)
print(my_counter()) # 11print(my_counter()) # 12print(my_counter(5)) # 17print(your_counter()) # 101print(my_counter()) # 18 - still remembers its own stateOutput:
11121710118Each counter maintains its own state. This is cleaner than using global variables or closures.
5.2 Configuration Objects
I found this pattern useful for creating configurable validators:
class Validator: """A configurable validator that can be called like a function"""
def __init__(self, min_length, max_length, allowed_chars=None): self.min_length = min_length self.max_length = max_length self.allowed_chars = allowed_chars
def __call__(self, value): if not isinstance(value, str): raise TypeError("Value must be a string")
if not self.min_length <= len(value) <= self.max_length: return False
if self.allowed_chars and not all(c in self.allowed_chars for c in value): return False
return True
# Create specialized validatorsusername_validator = Validator(3, 20, allowed_chars="abcdefghijklmnopqrstuvwxyz0123456789_")password_validator = Validator(8, 100)comment_validator = Validator(1, 500)
# Use them like functionsprint(username_validator("alice123")) # Trueprint(username_validator("ab")) # False - too shortprint(username_validator("alice@123")) # False - @ not allowedprint(password_validator("secret123")) # TrueOutput:
TrueFalseFalseTrue5.3 Decorator Classes
Many decorators are implemented as callable classes because they need to maintain state:
import time
class Timer: """A decorator that times function calls"""
def __init__(self, precision=2): self.precision = precision self.total_time = 0 self.call_count = 0
def __call__(self, func): def wrapper(*args, **kwargs): start = time.perf_counter() result = func(*args, **kwargs) elapsed = time.perf_counter() - start
self.total_time += elapsed self.call_count += 1
print(f"{func.__name__} took {elapsed:.{self.precision}f}s") return result return wrapper
# Usagetimer = Timer(precision=4)
@timerdef slow_function(): time.sleep(0.1) return "done"
slow_function()slow_function()slow_function()
print(f"Total calls: {timer.call_count}, Total time: {timer.total_time:.4f}s")Sample output:
slow_function took 0.1003sslow_function took 0.1002sslow_function took 0.1001sTotal calls: 3, Total time: 0.3006s5.4 API Design Pattern
Callable objects can provide intuitive APIs for configuration:
class Database: def __init__(self, host, port): self.host = host self.port = port self._connected = False
def __call__(self, query): """Make the instance itself execute queries""" if not self._connected: raise RuntimeError("Not connected to database") return f"Executing: {query} on {self.host}:{self.port}"
def connect(self): self._connected = True print(f"Connected to {self.host}:{self.port}")
def disconnect(self): self._connected = False print("Disconnected")
# Intuitive APIdb = Database("localhost", 5432)db.connect()
# Now call the instance to execute queriesresult = db("SELECT * FROM users")print(result)
db.disconnect()Output:
Connected to localhost:5432Executing: SELECT * FROM users on localhost:5432Disconnected6. The Difference Between __init__ and __call__
This was a point of confusion for me initially, so let me clarify:
class Example: def __init__(self, name): """Called when creating an instance""" print(f"__init__ called with name={name}") self.name = name
def __call__(self, value): """Called when you use () on an instance""" print(f"__call__ called with value={value}") return f"{self.name}: {value}"
# __init__ is called hereobj = Example("MyObject")# Output: __init__ called with name=MyObject
# __call__ is called hereresult = obj("hello")# Output: __call__ called with value=helloprint(result)# Output: MyObject: helloOutput:
__init__ called with name=MyObject__call__ called with value=helloMyObject: helloThe key distinction:
__init__is called when you create an instance:ClassName(args)calls__init____call__is called when you call an instance:instance(args)calls__call__
7. Understanding Chained Calls: foo()()
Now I finally understand what foo()() means:
class Multiplier: def __init__(self, factor): self.factor = factor
def __call__(self, value): return value * self.factor
def get_multiplier(factor): """Returns a callable Multiplier instance""" return Multiplier(factor)
# Chained call breakdown:# 1. get_multiplier(3) returns a Multiplier instance# 2. That instance is callable (has __call__)# 3. (10) calls that instance
result = get_multiplier(3)(10)print(result) # 30
# Equivalent to:multiplier_obj = get_multiplier(3) # Returns Multiplier(3)result = multiplier_obj(10) # Calls __call__ on that instanceprint(result) # 30Output:
3030So foo()() works because:
foo()returns something (could be a function, or a class instance with__call__)- That something is callable
()calls it
8. Common Mistakes
I made several mistakes while learning this:
Mistake 1: Trying to Call Non-Callable Objects
class NotCallable: def __init__(self, value): self.value = value # No __call__ method!
obj = NotCallable(42)obj() # TypeError: 'NotCallable' object is not callableError:
TypeError: 'NotCallable' object is not callableThe fix: Always check with callable() if you’re unsure.
Mistake 2: Confusing __call__ with Instance Methods
class BadExample: def __call__(self, value): return value * 2
def process(self, value): return value * 2
obj = BadExample()
# These look similar but work differently:print(obj(5)) # Calls __call__: 10print(obj.process(5)) # Calls the method: 10
# The difference becomes clear with assignment:my_func = obj # Reference to the callable instanceprint(my_func(5)) # Still works: 10
my_method = obj.process # Reference to the bound methodprint(my_method(5)) # Works: 10
# But they're different types:print(type(obj)) # <class '__main__.BadExample'>print(type(obj.process)) # <class 'method'>Mistake 3: Not Handling State Correctly
class BuggyCounter: count = 0 # Class variable - shared by all instances!
def __call__(self): self.count += 1 return self.count
counter1 = BuggyCounter()counter2 = BuggyCounter()
print(counter1()) # 1print(counter1()) # 2print(counter2()) # 3 - Wait, why not 1?The problem: using a class variable instead of instance variable.
class FixedCounter: def __init__(self): self.count = 0 # Instance variable - separate for each instance
def __call__(self): self.count += 1 return self.count
counter1 = FixedCounter()counter2 = FixedCounter()
print(counter1()) # 1print(counter1()) # 2print(counter2()) # 1 - Correct!Output:
1219. Summary
I learned that Python’s callable objects, powered by the __call__ method, provide a powerful way to create function-like classes. The key insights are:
-
Any object with
__call__is callable: Python uses duck typing - if it has__call__, you can use()on it. -
__init__vs__call__:__init__is called when creating an instance:ClassName()__call__is called when calling an instance:instance()
-
Practical uses:
- Stateful functions that remember values between calls
- Configurable validators and processors
- Decorator classes with state
- Intuitive API design
-
Chained calls work because
foo()()is just calling whateverfoo()returns - if that return value is callable, the second()works.
Now when I see code like obj() or foo()(), I immediately know what’s happening: somewhere in the inheritance chain, there’s a __call__ method making that object callable.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Python Documentation: Emulating Callable Objects
- 👨💻 Python callable() Built-in Function
- 👨💻 Reddit Discussion: 'What is a callable in Python?'
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments