What Does foo()() Mean in Python? Double Parentheses Syntax Explained
1. The Problem
When I was reading through some Python code recently, I encountered a strange syntax that I hadn’t seen before:
result = foo()()Wait, what? Two sets of parentheses after a function name? At first, I thought maybe this was some kind of typo or a way to pass multiple arguments. I was confused because this doesn’t look like any function call I’ve seen before.
So I tried to understand what this syntax actually does and why anyone would write code this way.
2. What I Initially Thought (Wrong!)
My first instinct was that foo()() might be some kind of special syntax for passing arguments. I thought maybe it was equivalent to:
# This is WRONG - my initial misunderstandingfoo(arg1, arg2) # I thought foo()() was like this somehowBut when I tried running the code and experimenting with different examples, I realized I was completely wrong. The syntax has nothing to do with passing two arguments.
3. The Real Explanation
After some research and experimentation, I finally understood: foo()() is actually two separate function calls happening in one line.
Here’s what happens step by step:
foo()is called first - this executes thefoofunctionfoo()returns something - and that something must be callable (another function, a class with__call__, etc.)- The second
()immediately calls whatever was returned
So foo()() is equivalent to:
returned_function = foo()result = returned_function()4. Basic Example
Let me show you a simple example to demonstrate this:
def foo(): """Returns another function that can be called""" def bar(): return "Hello from bar!" return bar
# Double parentheses in actionresult = foo()() # First calls foo(), then calls the returned bar()print(result) # Output: Hello from bar!
# This is equivalent to:returned_func = foo()result = returned_func()print(result) # Output: Hello from bar!When I ran this code, I got:
Hello from bar!Hello from bar!This confirmed my understanding. The first foo() returns the inner function bar, and then the second () calls bar.
5. Why Would You Use This?
I discovered several practical use cases for this pattern:
5.1 Factory Pattern
You can create specialized functions dynamically:
def create_multiplier(factor): """Factory that creates specialized multiplier functions""" def multiplier(number): return number * factor return multiplier
# Create specialized functionsdouble = create_multiplier(2)triple = create_multiplier(3)
print(double(5)) # Output: 10print(triple(5)) # Output: 15
# Or use double parentheses directlyprint(create_multiplier(4)(5)) # Output: 205.2 Decorator Pattern
This pattern is actually very common in decorators:
def decorator(func): def wrapper(): print("Before function call") result = func() print("After function call") return result return wrapper
@decoratordef say_hello(): return "Hello!"
# The @decorator syntax is actually equivalent to:# say_hello = decorator(say_hello)
print(say_hello())Output:
Before function callAfter function callHello!5.3 Callable Classes
I also learned that classes can be callable if they define the __call__ method:
class Greeter: def __init__(self, name): self.name = name
def __call__(self, greeting): return f"{greeting}, {self.name}!"
def create_greeter(name): return Greeter(name)
# Double parentheses with callable classmessage = create_greeter("Alice")("Hello")print(message) # Output: Hello, Alice!This works because when you call create_greeter("Alice"), it returns a Greeter instance, and since Greeter has a __call__ method, you can call the instance itself with ("Hello").
6. Common Mistakes
When experimenting, I found a few things that can go wrong:
6.1 Forgetting to Return a Callable
def foo(): return "not a function"
foo()() # TypeError: 'str' object is not callableThis raises:
TypeError: 'str' object is not callable6.2 Not Understanding What Gets Returned
If you don’t know what foo() returns, you can’t predict what the second () will do. Always check the return type.
7. Summary
I learned that foo()() in Python is simply a shorthand for calling a function that returns another callable, then immediately calling that returned callable. This pattern is commonly used in:
- Factory patterns to create specialized functions
- Decorators to return wrapper functions
- Closures to capture and use external variables
- Callable classes with
__call__methods
The key insight is: functions in Python can return other functions, and anything callable can use this double parentheses syntax.
If you encounter this syntax in the wild, just remember: it’s two function calls, not one special syntax. Break it down step by step, and it becomes much clearer.
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:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments