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.
Ouvir o resumo desta aula
Um recap de cerca de 2 minutos na voz do Valim, para ouvir no trânsito ou na academia.
Ler a transcrição do resumo
Resumo da aula: A sintaxe do arroba.
Os objetivos desta aula. 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.
Veja o essencial, parte por parte.
O que o arroba faz, em resumo. Escrever @deco acima de def func(): aplica o decorador deco à função func.
Provando que é só um atalho. Veja @registrar acima de uma def como registrar(essa_função) aplicado ali mesmo.
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.
Esse foi o resumo do essencial. Para se aprofundar, leia a aula completa e responda os exercícios.
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.