It has some possible uses. The main ones are these two:
factory functions
This may be the primary use. As functions are first class objects in Python, each time a function containing others is called, the internally declared functions are re-created (but not compiled again: the bytecode of nested functions is created in a previous step). They will have access to the external function variables, which will also be separated for each call (which creates a closure).
I think one of the most common uses is when writing a decorator in Python. Decorators in Python are functions that receive as another parameter another function. They return a callable object, usually a function as well, which can execute some code before and after the original function call. So the code for a simple decorator looks like this:
def decorator(func):
def wrapper(*args, **kwargs):
# código anterior a chamada original
...
result = func(*args, **kwargs)
# código posterior a chamada original
...
return result
return wrapper
@decorator
def minha_funcao():
...
In this case, every time "my_function" is called, what will be executed will be the wrapper
function declared within decorator
- but a wrapper
function in which the func
variable will be exactly the parameter of the function decorator
that receives minha_funcao
original as parameter.
If the decorator is used more than once, func
will receive the other decorated functions, and a wrapper
function will be created for each use.
It is interesting to keep in mind that a nested function can access the variables of the external functions, and in Python 3, to assign new values to these variables, using the nonlocal
statement (in Python 2, external variables were read-only).
Readability
Python deliberately restricts "lambda" functions to being just an expression. In general, "lambda" functions are used as parameters for other functions, for example, to obtain the sort key of a string in the sort
method, or a command to be executed when a button is clicked from a graphic program .
If the function to be passed as a parameter is a little more complex, and you need to have variables, if
s, etc ... it is already worth declaring it as an independent, nested function.
Nothing would prevent it from preventing this nested function from being outside the main code - but the nested declaration allows it to be close to the point where it is used once - and if that logic is related to the outside function.