Skip to content

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 misunderstanding
foo(arg1, arg2) # I thought foo()() was like this somehow

But 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:

  1. foo() is called first - this executes the foo function
  2. foo() returns something - and that something must be callable (another function, a class with __call__, etc.)
  3. The second () immediately calls whatever was returned

So foo()() is equivalent to:

equivalent.py
returned_function = foo()
result = returned_function()

4. Basic Example

Let me show you a simple example to demonstrate this:

basic_example.py
def foo():
"""Returns another function that can be called"""
def bar():
return "Hello from bar!"
return bar
# Double parentheses in action
result = 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:

factory_pattern.py
def create_multiplier(factor):
"""Factory that creates specialized multiplier functions"""
def multiplier(number):
return number * factor
return multiplier
# Create specialized functions
double = create_multiplier(2)
triple = create_multiplier(3)
print(double(5)) # Output: 10
print(triple(5)) # Output: 15
# Or use double parentheses directly
print(create_multiplier(4)(5)) # Output: 20

5.2 Decorator Pattern

This pattern is actually very common in decorators:

decorator_example.py
def decorator(func):
def wrapper():
print("Before function call")
result = func()
print("After function call")
return result
return wrapper
@decorator
def say_hello():
return "Hello!"
# The @decorator syntax is actually equivalent to:
# say_hello = decorator(say_hello)
print(say_hello())

Output:

Before function call
After function call
Hello!

5.3 Callable Classes

I also learned that classes can be callable if they define the __call__ method:

callable_class.py
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 class
message = 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

mistake_not_callable.py
def foo():
return "not a function"
foo()() # TypeError: 'str' object is not callable

This raises:

TypeError: 'str' object is not callable

6.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