How do nested functions work in Python?


In this article, we will explain nested/inner functions in Python and how they work with examples.

Nested (or inner) functions are functions defined within other functions that allow us to directly access the variables and names defined in the enclosing function. Nested functions can be used to create closures and decorators, among other things.

Defining an inner/nested Function

Simply use the def keyword to initialize another function within a function to define a nested function.

The following program is to demonstrate the inner function in Python −

Example

# creating an outer function def outerFunc(sample_text): sample_text = sample_text # creating an inner function def innerFunc(): # Printing the variable of the parent class(outer class) print(sample_text) # calling inner function innerFunc() # Calling the outer Function by passing some random name outerFunc('Hello tutorialspoint python')

Output

On executing, the above program will generate the following output −

Hello tutorialspoint python

Here, innerFunc() is declared inside the outerFunc(), making it an inner function. We must first call outerFunc() before we can call innerFunc(). The outerFunc() will then call the innerFunc(), which is defined within it.

It is essential that the outer function be called so that the inner function can execute.

Without Calling Outer Function

Example

# creating an outer function def outerFunc(sample_text): sample_text = sample_text # creating an inner function def innerFunc(): print(sample_text) # calling inner function innerFunc()

Output

On executing, the above program will generate the following output −


When run, the above code will return no results.

Scope of Variable in Nested Function

The scope of a variable is the location where we can find a variable and access it if necessary.

It is well-understood how to access a global variable within a function, but what about accessing the variable of an outside function?

The following program demonstrates the scope of the nested functions −

Example

# creating an outer function def outerFunc(): sample_str = 'Hello tutorialspoint python' # creating an inner function def innerFunc(): print(sample_str) # calling an inner function inside the outer function innerFunc() # calling outer function outerFunc()

Output

On executing, the above program will generate the following output −

Hello tutorialspoint python

It is clear from the above example that it is equivalent to accessing a global variable from a function.

Assume you wish to modify the variable of the outer function.

Example

The following program changes the value of a variable inside the nested function(inner function) −

# creating an outer function def outerFunc(): sample_str = 'Hello tutorialspoint python' # creating an inner function def innerFunc(): # modifying the sample string sample_str = 'Welcome' print(sample_str) # calling an inner function inside the outer function innerFunc() print(sample_str) # calling outer function outerFunc()

Output

On executing, the above program will generate the following output −

Welcome
Hello tutorialspoint python

Here, the value of the outer function's variable remains unchanged. However, the value of the outer function's variable can be modified. There are several methods for changing the value of the outer function's variable.

Using an iterable of inner functions

The Following program demonstrates how to use modify iterables in inner functions −

# Creating outer function def outerFunc(): # Creating an iterable sample_str = ['Hello tutorialspoint python'] # Creating inner Function/Nested Function def innerFunc(): # using an iterable to modify the value sample_str[0] = 'Welcome' print(sample_str) # Calling the inner function innerFunc() # Printing variable of the outer function print(sample_str) # Calling the outer function outerFunc()

Output

On executing, the above program will generate the following output −

['Welcome']
['Welcome']

Why should you use nested functions?

Encapsulation and closures/factory functions are two of the most common reasons for using nested functions.

Data encapsulation

There are cases when you wish to encapsulate a function or the data it has access to in order to prevent it from being accessed from other parts of your code.

When you nest a function like this, it becomes hidden to the global scope. Because of this characteristic, data encapsulation is also known as data hiding or data privacy.

# creating an outer function def outerFunc(): print("This is outer function") # creating an inner function def innerFunc(): print("This is inner function") # calling an inner function inside the outer function innerFunc() # calling inner function outside the outer function innerFunc()

Output

On executing, the above program will generate the following output −

Traceback (most recent call last):
  File "main.py", line 11, in <module>
    innerFunc()
NameError: name 'innerFunc' is not defined

The inner function in the code above is only accessible from within the outer function. If you attempt to call inner from outside the function, you will see the error shown above.

Instead, you must call the outer function as follows.

# creating an outer function def outerFunc(): print("This is outer function") # creating an inner function def innerFunc(): print("This is inner function") # calling an inner function inside the outer function innerFunc() # calling outer function outerFunc()

Output

On executing, the above program will generate the following output −

This is outer function
This is inner function

Closures

But what if the outer function returns the inner function itself, rather than invoking it as in the previous example? In that instance, you'd have something called closure.

The conditions that must be met in order to build a closure in Python are as follows.

  • A nested function is required.

  • The inner function must refer to a value that is defined in the enclosing scope.

  • The nested function must be returned by the enclosing function.

Example

def number_1(a): def number_2(b): return a*b return number_2 print(number_1(3)(2))

Output

On executing, the above program will generate the following output −

6

Closures allow you to pass data to inner functions without first passing it to outer functions with parameters. They also allow the inner function to be called from outside the encapsulating outer function. All of this with the previously mentioned benefit of data encapsulation/hiding.

Conclusion

This article taught us about inner functions, the purpose of nested functions, how they work, and the scope of nested functions in Python.

Start learning Python from here: Python Tutorial

Updated on: 28-Sep-2023

6K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements