Como usar funções aninhadas no Python

Como usar funções aninhadas no Python
Este artigo abordará um guia sobre o uso de funções aninhadas em Python. Funções aninhadas ou funções internas são definidas dentro de outras funções python. Eles são úteis em certos padrões de programação e casos de uso. Alguns deles serão explicados neste artigo. Todas as amostras de código deste artigo são testadas com Python 3.9.5 no Ubuntu 21.04.

Sobre funções aninhadas / internas

Funções aninhadas, como o nome sugere, são funções python que são criadas dentro de outras funções python. Além de seu próprio escopo, a função interna tem acesso aos objetos disponíveis no escopo da função externa. A função interna pode ser denominada como um único objeto Python com seus próprios dados e variáveis. Esta função interna é protegida pela função externa e não pode ser chamada ou referida do escopo global. Dessa forma, a função interna atua como uma entidade oculta que funciona dentro dos limites da função externa apenas e o escopo global permanece inconsciente disso. Este processo também é conhecido como "encapsulamento" na programação. Aqui está um exemplo de uma função aninhada em Python.

def visibile_outer_function (nome):
def hidden_inner_function ():
impressão (nome)
hidden_inner_function ()
visibile_outer_function ("John")
hidden_inner_function ()

A função externa leva um argumento obrigatório chamado "nome". A função interna tem acesso ao escopo da função externa para que possa usar a variável de nome. Uma chamada para a função interna é então feita na função externa. Em seguida, uma chamada para funções interna e externa é feita no escopo global. Depois de executar a amostra de código acima, você deve obter a seguinte saída:

John
Traceback (chamada mais recente):
Arquivo "Main.py ", linha 9, em
hidden_inner_function ()
NomeError: Nome 'hidden_inner_function' não está definido

Como você pode ver na saída, a função externa funciona bem quando você a chama de escopo global. Um erro é lançado quando você tenta chamar a função interna, pois nada está disponível no escopo global.

Funções internas Use casos

Agora que você tem algum entendimento sobre funções aninhadas, você pode se perguntar sobre a utilidade deles e quando usá -las. Um dos usos mais comuns das funções internas é a criação de funções auxiliares na função principal. As funções internas também podem ser usadas como decoradores e podem ser usadas para implementar o fechamento em seu programa. Esses casos de uso são explicados abaixo com exemplos.

Criando uma função auxiliar

As funções auxiliares são como quaisquer outras funções do Python, mas são chamadas de funções "auxiliares" porque podem ajudar a organizar melhor o código complexo e podem ser reutilizadas qualquer número de vezes para evitar a repetição de código. Abaixo está uma amostra de código que ilustra uma função auxiliar interna.

def get_ticket_price (nome):
membros = ["Tony", "Peter", "Mark"]
Preço = 10
def get_discounted_price (desconto = 1.0):
Retorno (preço * desconto)
Se o nome nos membros:
ticket_price = get_discounted_price (desconto = 0.50)
outro:
ticket_price = get_discounted_price ()
Print ("Preço do ingresso para" + nome + "é: $" + str (ticket_price))
get_ticket_price ("Tony")
get_ticket_price ("John")

A principal função externa chamada é "get_ticket_price". É preciso o nome de uma pessoa como argumento obrigatório. A função "get_discounted_price" é uma função auxiliar interna que toma "desconto" como um argumento opcional. A lista "membros" contém nomes de todos os membros registrados que são elegíveis para um desconto. Um preço com desconto para os membros é calculado chamando a função interna e fornecendo um valor de desconto como argumento. Esta função auxiliar pode ser chamada várias vezes com base nos requisitos e você também pode alterar a lógica dentro da função interna. Assim, as funções auxiliares internas permitem simplificar o código e evitar repetição desnecessária. Depois de executar a amostra de código acima, você deve obter a seguinte saída:

O preço do ingresso para Tony é: $ 5.0
O preço do ingresso para John é: $ 10.0

Como você pode ver na saída acima, Tony recebe um desconto no preço do ingresso, pois está na lista de membros.

Implementando fechamentos

O fechamento são instâncias de funções internas que são devolvidas por funções externas. Essas funções internas têm acesso ao escopo das funções externas e continuam a ter acesso ao escopo da função externa, mesmo depois que a função externa parou de executar. Dê uma olhada no exemplo de código abaixo:

def get_discounted_price (preço):
DEF DECOGADO_PRICE (desconto):
Preço de retorno * desconto
Retornar desconto_price
primeiro_discount = get_discounted_price (10)
Second_discount = get_discounted_price (10)
Imprimir (First_Discount (0.50))
Print (Second_Discount (0.60))

A função externa "get_discounted_price" retorna uma referência à função interna chamada "DOLGED_PRICE". Observe que, na declaração de retorno, a função é chamada sem aparelho. Em seguida, duas novas instâncias chamadas "First_Discount" e "Second_DiCount" são criadas chamando a função externa e um valor para o argumento de "preço" é fornecido a essas chamadas. Nesse momento, a função externa terminou de executar, mas seu estado foi salvo nos objetos First_Discount e Second_Discount. Agora, quando você liga para as instâncias First_Discount e Second_Discount com aparelhos e argumentos, eles já terão acesso a uma variável chamada Price, juntamente com seu valor. O argumento fornecido a essas instâncias agora vai para a função interna que retorna um resultado.

Depois de executar a amostra de código acima, você deve obter a seguinte saída:

5.0
6.0

Os fechamentos são geralmente usados ​​em situações em que seu programa exige preservar o estado de uma função.

Criando funções de decoração

As funções do decorador no Python modificam o comportamento de uma função python existente sem alterá -la. Portanto, quando você anexa um decorador a uma função, você pode adicionar funcionalidade adicional à função ou modificar seu comportamento, mantendo seu comportamento original intacto. Um decorador típico de Python se parece com o seguinte:

@decorador
Def Decorated ():
passar

Aqui "@Decorator" modificará o comportamento da função "decorada". Você pode criar funções de decorador usando funções aninhadas. Para criar um decorador, defina uma função e transmiti -la para uma função externa como um argumento. Esta função passada é então chamada dentro de outra função interna, onde você pode usá -la e implementar a lógica. Finalmente a função externa retorna a função interna que contém o comportamento modificado. Dê uma olhada no exemplo de código abaixo.

def get_discounted_price (valor):
DEF DECONED_PRICE ():
preço = valor ()
new_price = preço * 0.50
retornar new_price
Retornar desconto_price

A função externa "get_discounted_price" passa outra função chamada "quantidade" como um argumento. A função interna faz uso da função passada e adiciona um certo comportamento a ela. A função externa retorna uma referência à função interna que contém o comportamento modificado. Depois de definir o decorador, você pode chamá -lo da seguinte maneira:

@get_discounted_price
def get_price ():
retornar 10
print (get_price ())

Os decoradores são anexados a funções cujo comportamento você está tentando modificar. Eles sempre começam com o símbolo "@". Ao usar o decorador aqui, você está passando pela função "get_price" para a função "get_discounted_price" como um argumento. Agora, quando você chama a função get_price, você não receberá 10 como saída, mas um número modificado pelo decorador get_discounted_price. Depois de executar a amostra de código acima, você deve obter a seguinte saída:

5.0

O uso do decorador mostrado acima é equivalente ao seguinte código:

def get_discounted_price (valor):
DEF DECONED_PRICE ():
preço = valor ()
new_price = preço * 0.50
retornar new_price
Retornar desconto_price
def get_price ():
retornar 10
final_price = get_discounted_price (get_price)
print (final_price ())

Em vez de usar uma sintaxe "@Decorator" como uma abreviação, você pode simplesmente criar uma nova instância da função externa e fornecer outra função como um argumento. O resultado final dos dois padrões de codificação é o mesmo. Como os decoradores mantêm o comportamento da função original intacto, eles são realmente úteis se você quiser chamá -los caso a caso e, ao mesmo tempo, preservar a implementação de baunilha de uma função decorada.

Conclusão

Você pode usar funções aninhadas de várias maneiras para criar funções internas que adicionam funcionalidade e lógica extras à função externa. Alguns dos casos de uso mais comuns para funções aninhados foram explicados no artigo. Você também pode criar suas próprias implementações de funções internas, pois todas as funções são tratadas como objetos de primeira classe no Python e elas podem ser devolvidas ou passadas como argumentos.