Olá, Alex. Como vai?
Chegar ao arquivo Alura ex037.py explorando esse conceito é um marco fantástico na sua jornada! O que você implementou nesse script não é apenas uma função comum, mas sim um dos conceitos mais refinados, bonitos e poderosos da ciência da computação: uma Closure (Fechamento).
A arquitetura do seu código está excelente. Embora parte da função interna esteja oculta no topo da imagem, a lógica fica perfeitamente clara nos passos 3 e 4. Você criou uma função fábrica (criar_calculador_desconto) que configura um ambiente na memória e "fabrica" uma nova função customizada (calcular_preco) que carrega consigo, de forma permanente, o valor da porcentagem que o usuário digitou. O teste no terminal com o valor de 1220.20 e o desconto de 10 resultando em 1098.18 mostra que os cálculos de ponto flutuante funcionaram perfeitamente!
Para te ajudar a consolidar de vez a teoria por trás das Closures e elevar ainda mais o nível técnico do seu código, quero compartilhar uma explicação visual de como o Python gerencia isso na memória e duas ótimas dicas práticas:
No desenvolvimento de software tradicional, quando uma função termina de rodar, todas as variáveis locais criadas dentro dela são limpas da memória do computador.
A Closure quebra essa regra de forma elegante. Quando a função externa criar_calculador_desconto termina sua execução e dá o return aplicar_desconto, o Python cria um "escopo estendido" (chamado de ambiente fechado). A função interna mantém um link direto para a variável porcentagem, mesmo que a função pai já tenha deixado de existir.
No seu passo 3, quando você executou calcular_preco = criar_calculador_desconto(10), a variável calcular_preco se transformou em uma função especializada em dar 10% de desconto. Se na linha seguinte você criasse um calcular_black_friday = criar_calculador_desconto(50), o Python isolaria um novo bloco de memória focado em dar 50% de desconto, sem que uma função interfira no comportamento da outra.
No seu exercício anterior (Alura ex033.py), conversamos sobre a importância de proteger as casas decimais quando trabalhamos com dinheiro, e achei ótimo que você manteve a entrada como float().
Para deixar o visual do terminal ainda mais profissional e garantir que o sistema sempre mostre os centavos da compra (mesmo que o resultado dê um número redondo), você pode aplicar aquela formatação de duas casas decimais (:.2f) diretamente na f-string da linha 24:
# O :.2f garante a exibição com duas casas decimais padrão de moeda
print(f"Preço final com desconto: R$ {preco_final:.2f}")
Dominar essa técnica abre portas para você entender como grandes frameworks e bibliotecas profissionais de mercado operam por trás dos panos. As Closures são a base de:
@decorators): Recursos do Python usados para adicionar comportamentos extras (como checar se um usuário está logado ou medir o tempo de execução de um bloco) sem precisar modificar o código original da função.Parabéns por encarar um dos temas mais conceituais e avançados da manipulação de funções em Python com tanto capricho e organização nos comentários. Alcançar o exercício 37 com esse nível de código é uma conquista gigante! Continue firme nessa constância exemplar.
Espero que possa ter lhe ajudado!