Functions in Functions

In Python, you can actually have functions inside of functions.

def best_movie(n):
    def karen():
        print "There's a 30% chance that it's already raining!"

    def gretchen():
        print "Oh my GOD Karen, you're so stupid!"

    Karen()
    Gretchen()

Seems interesting. But why would this matter? Can’t we just do the print statements inside of the original best_movie function?

Partial Functions

To begin to understand the usefulness of this feature, we need to introduce the concept of partial functions.

def add_two_nums(a, b):
    return a + b

This function is simple enough. It takes two parameters, a and b, and gives back the result of the two added together. But what if we wanted to

>>> print add_two_nums(1, 1)
2

Voila! The axioms of mathematics hold and 1 + 1 is indeed 2.

So what the heck is a partial function? Check this out.

from functools import partial

add_one = partial(add_two_nums, 1)

So now what happens if we run add_three?

>>> print add_one(1)
2
>>> print add_one(3)
4

Wow! We created a function that adds 1 to any input given. We can think of the add_three function almost like the following:

def add_two(1, b):
    1 + b

Note that the above is not legal Python – we are using it just to illustrate the concept. In other words, a partial function is one where we can give only some of the parameters of a function, and create a new function that takes the rest of the parameters.

Here is a more complicated example.

from functools import partial

def f(a, b, c, x):
    return 1000*a + 100*b + 10*c + x

g = partial(f, 3, 1, 4)

print g(5)

Which will print 3145.

Closure

Is there a way we can do this without that annoying from functools import partial business? Sure we can!

def power_raise(n):
    def number(x):
        return x ** n
    return number

square = power_raise(2)
print square(12)
print square(10)

The printed output is

144
100

Wow! So we can actually create partial functions by using nested functions. This is called a closure, which is a tool to give local scope to a different function.

We will come back to this notion of functions within functions later on. For now, it’s enough if you understand how partial functions work and how you can create them.