Functions are first-class objects in Python.
You have no doubt encountered this on the command line if you have typed the name only of a function without parentheses.
In [2]: a
Out[2]: <function __main__.a>
When you see a(b)(c)
it is a method of chaining:
- The function
a
is defined to return another function.
a(b)
calls a
and returns that reference (to a callable function)
a(b)(c)
calls whatever function was returned by a
with c
as an argument.
This is equivalent to the following:
new_func = a(b)
new_func(c)
An example:
In [1]: def multiply_by(x):
...: def multiply_by_x(y):
...: return x * y
...: return multiply_by_x # notice no parens
...:
In [2]: multiply_by(10)
Out[2]: <function __main__.multiply_by_x>
Notice when you call this you get a function object. (This is what I mean when I am saying a "reference to a function" or the like.)
In [3]: multiply_by(10)(5)
Out[3]: 50
You're calling the function returned by multiply_by()
with 5 as an argument, and it's exactly the same as doing:
In [4]: multiply_by_10 = multiply_by(10)
In [5]: multiply_by_10(4)
Out[5]: 40
In [6]: multiply_by_10(8)
Out[6]: 80
The cool thing about doing this, as you can see from this example, is that now your multiply_by
function is a factory for functions that multiply by something. Above, we created multiply_by_10
which, obviously, multiplies what you feed it by 10. We can just as easily do:
In [7]: multiply_by_5 = multiply_by(5)
and have a function that multiplies by 5. This is obviously extremely useful. Incidentally, it's also how Python's decorators work.
Thanks @MarkusMeskanen in the comments for pointing out a way to make my silly example into a cooler one!
See also: