Let’s look at examples of the benefits of nested Python functions and how to use them to encapsul closures, and decorators.
Nested [or inner, nested] functions are functions that we define inside other functions to directly access the variables and names defined in the enclosing function. Nested functions have many uses, primarily for creating closures and decorators.
In this guide, we will
learn how to provide encapsulation and hide functions from external access
write helper functions to make code easier to reuse
implement closures to persist state between calls
let’s create decorators to add behaviour to existing functions
Let’s start with a code example containing a nested function:
def outer_func[]: def inner_func[]: print["Hello, World!"] inner_func[] outer_func[]
OUTPUT
Hello, World!
In this code, we define internally to display a string . To do this, we call on the last line . inner_func[] outer_func[] Hello, World! inner_func[] outer_func[]
The major use of internal functions is their easiness to access variables and objects from an subscribed [“external”] function. The enclosing function provides a namespace available to the nested function:
def outer_func[who]: def inner_func[]: print[f"Hello, {who}"] inner_func[] outer_func["World!"]
OUTPUT
Hello, World!
Now we can pass a string as an argument to the function, and will refer to this argument through the name . This name is defined in the local scope. The names we defined in the local scope of the outer function are defined as. They are non-local from a point of view. external_func[] inner_func[] who outer_func[] nonlocal inner_func[]
Another example of a more complex nested function:
def factorial[number]: if not isinstance[number, int]: raise TypeError["The number must be whole."] if number < 0: raise ValueError["The number must be non-negative."] #Factorial calculation def inner_factorial[number]: if number