How Do Nested Functions Work in Python?

Functions are handled as first-class objects in Python. In a language, first-class objects are treated consistently throughout. Data structures, control structures, and argument passing are some of the possible uses for them. If a programming language treats functions as first-class objects, then it is said to support first-class functions. Python supports the First-Class function notion.

Qualities of first-class functions include:

  • An instance of the Object type is a function.
  • The function can be kept in a variable.
  • The function can be sent to another function as an argument.
  • A function can return its function.
  • These functions can be kept in data structures like lists, hash tables, and so on.

Inner Functions

An inner function, often referred to as a nested function, is declared inside another function. The enclosing scope's variables are accessible to nested functions. The purpose of inner functions is to shield them from anything that occurs outside of the function. Another name for this procedure is encapsulation.

Example:

Output:

 
We are Learning Python from Javatpoint.   

Explanation:

The inner functions inside the outer function are demonstrated in this Python code. The txt parameter provided to the outer function is printed by the inner function inner function, which is defined by the outer function. sometxt is the variable containing text: 'We are Learning Python from Javatpoint.' and is passed as a parameter to outerFunc, which then calls innerFunc and prints the result. This demonstrates the idea of Python's nested functions.

Since innerFunc() is declared within outerFunc() in the example above, it is an inner function. We need to call outerFunc() before we can call innerFunc(). After that, because innerFunc() has been declared within it, outerFunc() will call innerFunc().

The outer function must be called in order for the inside function to run. To illustrate this, look at the example below:

Output:

 
This code will return nothing when executed.   

Explanation:

The outer function defined by this Python code accepts a text argument and defines an inner function inside of it. The inner function prints the text variable from the outer function. Nevertheless, when the outer function is used, no apparent output is produced since it is called without any print statements or return values.

Scope of Variable in Nested Function

The scope of a variable is the place where we may locate it and access it when needed.

While accessing a global variable within a function is well-known, what about accessing a variable outside of a function? Take this as an example:

Output:

 
We are Learning Python from Javatpoint.   

Explanation:

The function funcOne in this Python code has a nested function called funcTwo. Lexical scoping rules allow the variables to be available within funcTwo even if it is defined within funcOne. The output " We are Learning Python from Javatpoint." is produced when funcOne is executed, invoking funcTwo to print the value of sometxt.

It is evident from the example above that it is comparable to using a function to retrieve the global variable. Let's now assume that you wish to modify the outer function's variable.

Output:

 
I love Learning Python from Javatpoint.
We are Learning Python from Javatpoint.   

Explanation:

The function funcOne in this Python code defines a variable called sometxt, and its value is ' We are Learning Python from Javatpoint.'. A nested function called funcTwo exists inside funcOne, and it redefines sometxt to mean " I love Learning Python from Javatpoint." Upon calling funcTwo, " I love Learning Python from Javatpoint." is printed as the modified value of sometxt. But " We are Learning Python from Javatpoint." is printed when funcOne prints sometxt, referring to the outer sometxt. As can be observed, the outer function's variable value has not changed.

Nonetheless, the outer function's variable value is modifiable. The outer function's variable can be changed in several different ways.

Making Use of an Iterable:

Output:

 
['I love Learning Python from Javatpoint.']
['I love Learning Python from Javatpoint.']   

Explanation:

'We are Learning Python from Javatpoint.' is the only entry in the list sometxt that is initialized by the function funcOne in this Python code. One nested function, funcTwo, resides within funcOne and changes the first element of sometxt to 'I love Learning Python from Javatpoint.'. The updated list sometxt, which includes the amended element, is printed when function funcTwo is invoked. In a similar way, the changed element in the updated list is displayed by funcOne when it displays sometxt, reflecting the change performed by funcTwo.

Using Nonlocal Keyword:

Output:

 
I love Learning Python from Javatpoint.
I love Learning Python from Javatpoint.   

Explanation:

The variable sometxt in this Python code is not local to function funcTwo, but rather belongs to the enclosing function funcOne, as shown by the use of the nonlocal keyword within the nested function funcTwo. This permits funcTwo to change the value of sometxt that funcOne defined. It also impacts the value of sometxt in funcOne when funcTwo changes sometxt to 'I love Learning Python from Javatpoint.'. As a result, "I love Learning Python from Javatpoint." is printed as the updated value of sometxt by both funcTwo and funcOne.

Value Can Also Be Modified, As the Example Below Illustrates.

Output:

 
I love Learning Python from Javatpoint.
I love Learning Python from Javatpoint.   

Explanation:

The function funcOne in this Python code defines the variable funcOne.sometxt. The same variable funcOne.s is accessed and changed using dot notation (funcOne.sometxt) inside the nested function funcTwo. Consequently, the value of funcOne.sometxt for the funcOne function is also updated when funcTwo alters funcOne.sometxt to 'I love Learning Python from Javatpoint.'. Consequently, 'I love Learning Python from Javatpoint.' is the updated value of funcOne.sometxt that is printed by funcOne and funcTwo.

Python Closures

When values in surrounding scopes are not in memory, a closure is a function object that retains its memory.

  • It is a record that holds a function and its surroundings. Specifically, it is a mapping that links each function's free variable-that is, variables specified in the enclosing scope but utilized locally-to the value or reference to which the name was tied at the time the closure was formed.
  • Unlike simple functions, closures enable the function to access those captured variables even when it is called outside of its scope by using copies of the variables' references or values.

filter_none.

Output:

 
Welcome to Javatpoint Python Tutorial   

Explanation:

The sometxt variable defined in the outer function is printed by the inner function, innerFunc, which is declared by outer function in this Python code. Without invoking the inner function (i.e., without brackets), the outer function returns the inside function. The value of sometxt is captured, and a closure is created when outerFunc is called and assigned to funcOne. The output "Welcome to Javatpoint Python Tutorial!" is produced when funcOne is invoked later on. The innerFunc function, which is still able to access the text variable from the enclosing scope, is then executed. This illustrates how a function in Python may keep access to variables from its surrounding scope even after the outer function has completed running. This is known as a closure.

  • Closures facilitate the invocation of functions outside of their scope, as the code above illustrates.
  • Only the outer function is the scope of the inner function. However, we can simply expand its scope to call a function outside of it by using closures.

Output:

 
6
9
5
10   

Explanation:

This Python program uses a logger function that accepts an input function (add or sub) and outputs a new function called logFunction in order to illustrate closures. Before the function is executed, this logFunction records the function name and its parameters. The logger function is then used by the program to build logger routines for addition and subtraction (addLogger and subLogger). These logger functions illustrate the idea of closures, where the inner function (logFunction) keeps access to variables (function_as_parameter, args) from the outer function (logger) by first logging the function name and arguments when called with arguments.