Nested Functions in Python

Nested Functions in Python

Manav Narula Aug-10, 2021 May-28, 2021 Python Python Function

A function is a block of code that can be called again and again in a program. It can accept different arguments and can return some useful value. In all programming languages, we have built-in functions and user-defined functions.

In this tutorial, we will learn how to create and use nested functions in Python.

Most of the languages support the use and creation of nested functions. As the name suggests, a nested function is a function within a function. The function nested inside is called the inner function, and the enclosing function is called the outer function.

In the following code, we create a basic nested function.

def outer_f(s):
    def inner_f(s):
        print(s)
    inner_f(s)    
outer_f("Nested")        

Output:

Nested

Using the above example, we can get a little idea about the use of nested functions. They can be used to hide a function from the outside world and implement data encapsulation.

Another thing to know is that the nested function can use the variable used in the outer function. Such variables are called non-local. Nested functions can access them, but if we need to modify them, we have to use the nonlocal keyword.

Let’s see the following example.

def outer_f():
    s = 5
    def inner_f():
        nonlocal s
        s =  s+1
        return s
    return inner_f()    

print(outer_f())        

Output:

6

Here we would not be able to modify the s variable without using the nonlocal keyword.

Now imagine if the nested function returns some value. This brings us to another useful feature of nested functions and which is closure functions. These functions are dynamically created using nested functions. It may be an elegant and concise way to implement data hiding and use it as an alternative for classes.

See the following code.

def incrementer(x):
    def inc(y):
        return x + y
    return inc

by4 = incrementer(4)
by5 = incrementer(5)

print(by4(5), by5(5))

Output:

9 10

Now in the above code, we create a dynamic method to increment a number. The by4 and by5 are the two closure functions created using the nested function. This is mainly due to the ability of the nested functions to retain their state. It can be a decent alternative to classes and global variables when not too many attributes are involved. We can find out if a function is a closure using the __closure__ attribute. All functions have this attribute ad it returns some cell objects when used with a closure function.

The nested functions are also used for decorator functions. Decorator functions use a callable object like a class, function, and return another object. We use the @ sign to use a decorator before any such callable object. This way, we take the callable object as an argument of the decorator function and use it.

We create a very simple decorator function to understand this better in the following example.

def dec(func):
    def inner():
        print("Hello")
        func()
    return inner

@dec
def world():
    print("world")

world()

Output:

Hello
world

In the above example, we created a simple decorator function called dec(), which decorates the world() function by using it as an argument and printing an additional message.

Author: Manav Narula
Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn

Related Article - Python Function

  • Exit a Function in Python
  • Optional Arguments in Python
  • Fit a Step Function in Python
  • Built-In Identity Function in Python
  • Arguments in the main() Function in Python
  • Python Functools Partial Function