Python functions with multiple parameter brackets

Question:

I’ve been having trouble understanding what h(a)(b) means. I’d never seen one of those before yesterday, and I couldn’t declare a function this way:

def f (a)(b):
    return a(b)

When I tried to do def f (a, b):, it didn’t work either. What do these functions do? How can I declare them? And, finally, what’s the difference between f(a, b)and f(a)(b)?

Asked By: soleil

||

Answers:

Functions with multiple parameter brackets don’t exist, as you saw when you tried to define one. There are, however, functions which return (other) functions:

def func(a):
    def func2(b):
        return a + b
    return func2

Now when you call func() it returns the inner func2 function:

>>> func2 = func(1)  # You don't have to call it func2 here
>>> func2(2)
3

But if you don’t need the inner function later on, then there’s no need to save it into a variable and you can just call them one after the other:

>>> func(1)(2)   # func(1) returns func2 which is then called with (2)
3

This is a very common idiom when defining decorators that take arguments.


Notice that calling func() always creates a new inner function, even though they’re all named func2 inside of the definition of our func:

>>> f1 = func(1)
>>> f2 = func(1)
>>> f1(1), f2(1)
(2, 2)
>>> f1 is f2
False

And, finally, what’s the difference between f(a, b)and f(a)(b)?

It should be clear now that you know what f(a)(b) does, but to summarize:

  • f(a, b) calls f with two parameters a and b
  • f(a)(b) calls f with one parameter a, which then returns another function, which is then called with one parameter b
Answered By: Markus Meskanen

Lets say we have an expression like

f(a)(b)

then, f(a) returns a function itself which gets invoked with argument b. Consider the following example

def f(a):
   def g(b):
      return a * b
   return g

Then f(5)(4) evaluates to 5 * 4, since f(5) returns a function which is basically

def g(b):
   return 5 * b

One could now do stuff like this

mult_by_5 = f(5)
[mult_by_5(x) for x in range(10)]

Let’s be fancy, what about more nested functions?:

def f(a):
  def g(b):
    def h(c):
      return a * b *c
    return h
  return g
f(2)(3)(4) # 24
Answered By: Nicolas Heimann

f(a)(b) just means that the expression f(a) returns a value that is itself callable. It’s a short form of

g = f(a)
g(b)

You might be more comfortable adding a pair of redundant parentheses to emphasize that this is not a single syntactic construct.

(f(a))(b)  # f(a) is evaluated first, then the result is applied to b

It is exactly analogous to the same doubling of square brackets for indexing nested dictionaries.

d1[x][y]

is equivalent to

d2 = d1[x]
d2[y]
Answered By: chepner
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.