Módulo 12 - Decoradores

A sintaxe do arroba

10 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026

O que você vai aprender

  • Aplicar um decorador com o símbolo @ acima da def.
  • Provar que @deco é o mesmo que func = deco(func).
  • Entender por que o @ deixa o código mais limpo e explícito.
  • Reconhecer que o @ não muda nada da mecânica aprendida antes.

O que o arroba faz, em resumo

Na aula anterior, para usar o decorador tivemos que escrever uma linha extra: decorada = com_moldura(dizer_ola). Funciona, mas tem dois incômodos. O primeiro é que a moldura aparece longe da função, lá embaixo, então quem lê a def não sabe de cara que ela é decorada. O segundo é que criamos um nome novo, decorada, em vez de continuar usando dizer_ola. O símbolo @ resolve os dois de uma vez. Você escreve o nome do decorador com um @ na frente, na linha imediatamente acima da def, e o Python faz a reatribuição sozinho.

def com_moldura(func):
    def wrapper():
        print("=== inicio ===")
        func()
        print("=== fim ===")
    return wrapper

@com_moldura
def dizer_ola():
    print("Olá, mundo")

dizer_ola()
# === inicio ===
# Olá, mundo
# === fim ===

Com @com_moldura, o próprio nome dizer_ola já aponta para o wrapper.

Provando que é só um atalho

A melhor forma de perder o medo do símbolo @ é ver, lado a lado, que os dois jeitos produzem o mesmo resultado. Quando o Python encontra uma linha @com_moldura logo acima de def dizer_ola, ele define a função dizer_ola normalmente e, em seguida, executa dizer_ola = com_moldura(dizer_ola). É literalmente essa reatribuição, feita para você. Não há passo escondido nem comportamento especial: o decorador recebe a função, devolve o wrapper, e o nome passa a apontar para o wrapper.

# Estas duas versões são equivalentes.

# Versão 1: com o símbolo @
@com_moldura
def tarefa_a():
    print("tarefa A")

# Versão 2: na mão, sem o @
def tarefa_b():
    print("tarefa B")
tarefa_b = com_moldura(tarefa_b)

tarefa_a()   # === inicio === / tarefa A / === fim ===
tarefa_b()   # === inicio === / tarefa B / === fim ===

As duas versões fazem a mesma reatribuição; o @ apenas a escreve por você.

Confirmando o entendimento

Guarde a equivalência como um mantra: @deco acima de def func é igual a func = deco(func) escrito logo abaixo da definição. Toda vez que bater a dúvida sobre o que um @ faz, reescreva mentalmente na forma longa e a mágica some. Essa clareza vale ouro quando você lê bibliotecas de verdade, onde decoradores aparecem o tempo todo, em rotas de servidores web, testes e configuração. Na próxima aula, resolvemos um problema prático: o wrapper que escrevemos até agora só funciona com funções sem argumentos.

Teste rápido

A linha @com_moldura acima de def dizer_ola equivale a qual instrução?

Perguntas frequentes

O @ é obrigatório para usar decoradores?
Não. Você pode sempre escrever func = deco(func) na mão, e o efeito é idêntico. O símbolo @ existe só para deixar isso mais curto e visível, colado à definição da função. Na prática, quase todo mundo usa o @, mas entender a forma longa é o que dissolve a confusão.
Onde o @ precisa ser escrito?
Na linha imediatamente acima da palavra def da função que você quer decorar, com o nome do decorador logo após o @, sem espaço. Por exemplo, @com_moldura em uma linha e def dizer_ola(): na linha de baixo.
Posso aplicar mais de um decorador na mesma função?
Sim. Basta empilhar as linhas @ uma sobre a outra. Elas se aplicam de baixo para cima: o decorador mais próximo da def envolve a função primeiro, e o de cima envolve o resultado. É como colocar uma caixa dentro de outra caixa.
O que acontece com o nome original da função?
O nome passa a apontar para o wrapper devolvido pelo decorador. A função original ainda existe por dentro (o wrapper a chama), mas o nome que você usa agora executa a versão envolvida. Isso tem um efeito colateral no nome exibido da função, que a aula sobre functools.wraps resolve.
O @ funciona só com funções?
Neste curso usamos o @ sobre funções, que é o caso mais comum. Ele também pode decorar métodos e classes, com a mesma mecânica de reatribuição. Domine primeiro o caso de funções; os outros seguem a mesma lógica de @deco igual a alvo = deco(alvo).
Por que chamam o @ de açúcar sintático?
Porque ele adoça a escrita sem mudar o que é possível fazer. Tudo que o @ faz já era possível com uma reatribuição manual. Açúcar sintático é justamente uma forma mais curta e agradável de escrever algo que a linguagem já permitia de um jeito mais longo.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.