What is the purpose of declaring a function within a function?

Asked

Viewed 5,645 times

12

In Python it is possible to declare a function within another function, as shown in the following code.

def foo(palavra=None):
    print(palavra)
    def bar(outra_palavra=None):
        print(outra_palavra)


if __name__ == '__main__':
    foo(palavra='metodo main')

But what is the practical purpose of such language flexibility? In which scenario making use of such a tool enables a gain?

3 answers

17


One reason is encapsulation. If the internal function will be called only by this function there is no need to put out. Putting inside ensures that no one else can call.

One thing I notice is that people learn to program without understanding what they’re doing and one of the things that people don’t understand is the function of the function (intentional pun :) ). Functions serve to abstract algorithms. They serve to indicate with more clarity and organization what it is doing at the same time that it creates a canonical form of that operation. a concept known as DRY.

It is possible that something the external function does repeats itself and makes sense to abstract in a function. As only she needs this it is better not to expose to other parties. The less to expose has less worry and easier to maintain.

A cool feature is that you can return the function itself, ie your method prepares the function and delivery for those who need to use internal. This is done with a technique called anonymous function. So you create a named function and use its name as if it were a variable, then the function is not executed but passed on as if it were a given (this is optimized by pointer). Something like that:

def GeraCondicao(valor):
    def Condicao(item):
        return item > valor
    return Condicao

condicao = GeraCondicao(5)
for i in range(0, 10):
    if condicao(i)
        print i

I put in the Github for future reference.

Will print from 6 to 10.

In case I used a closure (another definition) since a given of the external function has been captured by the internal function

Obviously you can generate this condition in many ways, you can call other functions that create anonymous functions and compose the way you need.

Of course you don’t even need to return, you can just switch to another function that is calling right there where the internal function was created.

7

It has some possible uses. The main ones are these two:

function factory

That might be the main use. Since functions are first-class objects in Python, each time a function containing others is called, the functions declared internally are recreated (But not compiled again: the bytecode of the nested functions is created in an earlier step). They will have access to the external function variables, which will also be separated from each call (which creates a "closure").

I think one of the most common uses is when writing a Python decorator. Python decorators are functions that receive as a single parameter another function. They return a calling object, usually a function as well, which can execute some code before and after the call of the original function. So a simple decorator’s code goes 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, each time "my_function" is called, what will be executed will be the function wrapper sloped within the decorator - but a function wrapper where the variable func will be exactly the function parameter decorator who receives minha_funcao original as parameter.

If the decorator is used more than once, func will receive the other decorated functions, and a function will be created wrapper distinct 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, even assign new values to these variables , using the declaration nonlocal (in Python 2, the external variables were read-only).

readability

Python deliberately restricts the functions of the "lambda" type to being just an expression. In general, "lambda" functions are used as parameters for other functions, for example to obtain the sorting key of a sequence in the method sort, or a command to be executed when a graphical program button is clicked.

If the function to be passed as parameter is a little more complex, and needs to have variables, ifs, etc... already worth declaring it as an independent function, nested.

Nothing would prevent this nested function from being outside the main code - but the nested statement allows it to be near the point where it is used only once - and if that logic is related to the outside function.

3

Don’t confuse métodos de classe with funções.

It is not possible that a Método de Classe contains another Método de Classe declared within its scope.

Métodos de Classe are at all times associated with Classes. Can only be declared within a Classe. Métodos de Classe can only be called from the specification of your name Classe (static method) and/or from an instance of its Classe.

Already a função is independent, they can be declared within other funções as well as within Métodos de Classe. Notice that Funções declared within Classes, in fact, are Métodos de Classe!

Allow funções are declared within the scope of other funções and/or Métodos de Classe makes the encapsulamento.

Note that even programs written in a structured way can encapsular its functions, publishing to the outside scope (the client) only the functions that really matter.

His example reads that: The function foo() encapsulates the function bar(); It’s not interesting what function bar() is visible by the outside scope; The function bar() is intimately coupled to function foo();No one outside the scope of foo() is able to call bar().

Encapsulation, if applied properly, greatly increases the readability and reuse of the code, which in turn greatly facilitates its development and maintenance.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.