In Python, functions can be nested inside other functions. A nested function is only visible within the enclosing function. This allows us to create utility functions that are specific to a particular function and not needed elsewhere.

But why would we want to “hide” a function if it isn’t causing any harm? Well, it’s always good practice to hide functionality that is only relevant within a specific scope. Additionally, nested functions can make use of closures, which we’ll discuss later.

Here’s an example to illustrate nested functions:

def talk(phrase):
    def say(word):
        print(word)

    words = phrase.split(' ')
    for word in words:
        say(word)

talk('I am going to buy the milk')

If you want to access a variable defined in the outer function from the inner function, you need to declare it as nonlocal:

def count():
    count = 0
    
    def increment():
        nonlocal count
        count = count + 1
        print(count)

    increment()

count()

Declaring the variable as nonlocal is especially useful when working with closures, which we will explore in more detail later.