Como criar decoradores de função e encadeá-los?

Ana Maria Gomes
5 minutos de leitura

Conteúdos do tutorial

Decoradores de função são uma característica poderosa e expressiva do Python que permitem modificar o comportamento de uma função sem alterá-la permanentemente. Neste post, vamos explorar como criar decoradores e encadeá-los para aplicar múltiplas modificações a uma única função.

Entendendo Decoradores de Função no Python

Antes de mergulhar na criação de decoradores, é crucial entender que funções no Python são objetos de primeira classe. Isso significa que elas podem ser passadas adiante, atribuídas a variáveis e até definidas dentro de outras funções. Aqui está um exemplo simples para ilustrar isso:

def gritar(palavra="sim"):
    return palavra.capitalize() + "!"

# Atribuir a função a uma variável
berro = gritar

# Chamar a função usando a nova variável
print(berro())  # Saída: 'Sim!'

Funções também podem retornar outras funções, que é a base de como os decoradores funcionam:

def pegar_fala(tipo="gritar"):
    def gritar(palavra="sim"):
        return palavra.capitalize() + "!"
    def sussurrar(palavra="sim"):
        return palavra.lower() + "..."
    if tipo == "gritar":
        return gritar  
    else:
        return sussurrar

# Usar a função retornada
fala = pegar_fala()
print(fala())  # Saída: 'Sim!'

Criando Decoradores Simples

Um decorador é essencialmente uma função que recebe outra função como argumento e retorna uma nova função que adiciona algum tipo de funcionalidade. Veja como você pode criar um decorador simples:

def meu_decorador(uma_funcao_para_decorar):
    def o_envelope_ao_redor_da_funcao_original():
        print("Antes da função ser executada")
        uma_funcao_para_decorar()
        print("Depois da função ser executada")
    return o_envelope_ao_redor_da_funcao_original

Você pode usar este decorador para envolver qualquer função:

def uma_funcao_independente():
    print("Eu sou uma função independente.")

uma_funcao_independente_decorada = meu_decorador(uma_funcao_independente)
uma_funcao_independente_decorada()

Usando a sintaxe @, você pode aplicar o decorador diretamente a uma função:

@meu_decorador
def outra_funcao_independente():
    print("Me deixe em paz")

outra_funcao_independente()

Encadeando Decoradores

Você pode aplicar múltiplos decoradores a uma função empilhando-os uns sobre os outros:

def tornar_negrito(fn):
    def embrulho():
        return "<b>" + fn() + "</b>"
    return embrulho

def tornar_italico(fn):
    def embrulho():
        return "<i>" + fn() + "</i>"
    return embrulho

@tornar_negrito
@tornar_italico
def dizer():
    return "olá"

print(dizer())  # Saída: <b><i>olá</i></b>

A ordem dos decoradores é importante. No exemplo acima, @tornar_italico é aplicado primeiro, e depois @tornar_negrito.

Uso Avançado de Decoradores

Decoradores também podem aceitar argumentos e ser aplicados a métodos. Usando *args e **kwargs, você pode criar decoradores que aceitam qualquer número de argumentos:

def um_decorador_passando_argumentos_arbitrarios(funcao_para_decorar):
    def um_envelope_aceitando_argumentos_arbitrarios(*args, **kwargs):
        funcao_para_decorar(*args, **kwargs)
    return um_envelope_aceitando_argumentos_arbitrarios

Para passar argumentos para o próprio decorador, você pode criar um criador de decoradores:

def criador_de_decorador_com_argumentos(argumento_decorador1, argumento_decorador2):
    def meu_decorador(func):
        def embrulhado(*args, **kwargs):
            # Você pode acessar os argumentos do decorador aqui
            return func(*args, **kwargs)
        return embrulhado
    return meu_decorador

@criador_de_decorador_com_argumentos("arg1", "arg2")
def minha_funcao():
    pass

Resumo

Neste post, aprendemos como criar decoradores no Python e encadeá-los para adicionar múltiplas camadas de funcionalidade a uma função. Decoradores são uma ferramenta poderosa para estender o comportamento das funções de uma maneira limpa e legível. Lembre-se de que a ordem dos decoradores importa e que você pode usar *args e **kwargs para tornar seus decoradores mais flexíveis. Feliz decoração!

Inscreva-se gratuitamente e fique atualizado

Receba toda semana um resumo dos principais conteúdos da Asimov direto no seu e-mail. 100% livre de spam.

Áreas de interesse: