Módulo 12 - Decoradores
O caminho até o decorador
11 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026
O que você vai aprender
- Relembrar que em Python uma função é um objeto que pode ser passado e devolvido.
- Entender closure: uma função interna que lembra as variáveis da função externa.
- Construir um decorador manualmente, sem usar o símbolo @.
- Enxergar que decorar é envolver uma função em outra que adiciona comportamento.
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: O caminho até o decorador.
Os objetivos desta aula. Relembrar que em Python uma função é um objeto que pode ser passado e devolvido. Entender closure: uma função interna que lembra as variáveis da função externa. Construir um decorador manualmente, sem usar o símbolo @. Enxergar que decorar é envolver uma função em outra que adiciona comportamento.
Veja o essencial, parte por parte.
O que é um decorador, em uma ideia. Um decorador é uma função que recebe outra função e devolve uma nova função no lugar dela.
Closure, a peça que faltava. A parte que falta é conseguir devolver uma função nova.
Fixando a ideia central. Antes de conhecer o atalho do símbolo @ na próxima aula, garanta que a ideia base está firme.
Esse foi o resumo do essencial. Para se aprofundar, leia a aula completa e responda os exercícios.
O que é um decorador, em uma ideia
Decorador tem fama de assunto difícil, e quase sempre isso vem de começar pelo símbolo @ antes de entender a ideia por baixo. Vamos pelo caminho contrário. Um decorador não é um recurso mágico da linguagem; é um jeito de usar duas coisas que você já conhece. A primeira é que, em Python, uma função é um objeto como outro qualquer: você pode guardá-la numa variável, colocá-la numa lista, passá-la para outra função e devolvê-la de dentro de uma função. A segunda é a closure, uma função escrita dentro de outra que lembra das variáveis de fora. Junte as duas e o decorador aparece sozinho.
def saudacao():
return "Olá!"
# Uma função pode ir para uma variável, sem parênteses.
apontador = saudacao
print(apontador()) # Olá!
# E pode ser passada como argumento para outra função.
def executar_duas_vezes(func):
return func() + " " + func()
print(executar_duas_vezes(saudacao)) # Olá! Olá!Sem parênteses, saudacao é o objeto função; com parênteses, você a executa.
Closure, a peça que faltava
A parte que falta é conseguir devolver uma função nova. Para isso, escrevemos uma função dentro de outra. A função interna usa a variável da externa (a função recebida) e é devolvida para ser chamada depois. Como ela lembra dessa variável mesmo depois que a externa terminou, temos uma closure. Repare que devolvemos o objeto função, sem parênteses; quem recebeu decide quando chamar. Esse é o esqueleto exato de todo decorador que você vai escrever pelo resto do curso.
def com_moldura(func):
def wrapper():
print("=== inicio ===")
func()
print("=== fim ===")
return wrapper # devolve a função interna, sem chamar
def dizer_ola():
print("Olá, mundo")
# Envolvemos dizer_ola na moldura e guardamos o resultado.
decorada = com_moldura(dizer_ola)
decorada()
# === inicio ===
# Olá, mundo
# === fim ===com_moldura recebe uma função e devolve wrapper, que a chama entre duas linhas.
Leia esse exemplo com calma, porque ele é o coração do módulo. A função com_moldura é o decorador. Ela não faz nada sozinha: recebe uma função qualquer no parâmetro func, define uma função interna wrapper que chama func no meio de duas mensagens, e devolve wrapper. Quando escrevemos decorada = com_moldura(dizer_ola), a variável decorada passa a apontar para o wrapper, que por dentro lembra qual era a func original. Chamar decorada() executa a versão envolvida. Note que dizer_ola em nada foi alterada; ela continua intacta. O que ganhamos foi uma nova função com comportamento a mais ao redor dela.
Sem decorador
- Copiar as linhas de moldura dentro de cada função
- Repetir o mesmo trecho em vários lugares
- Mudar a moldura pede editar função por função
- A função mistura o que faz com o extra
Com decorador
- Escrever a moldura uma vez, no wrapper
- Reaproveitar em qualquer função
- Mudar a moldura em um lugar só
- A função original fica limpa e focada
Fixando a ideia central
Antes de conhecer o atalho do símbolo @ na próxima aula, garanta que a ideia base está firme. Um decorador é, em uma frase, uma função que recebe uma função e devolve uma função. A função devolvida (o wrapper) chama a original e acrescenta comportamento antes, depois, ou nos dois momentos. Nada nisso exige sintaxe nova; é tudo função de primeira classe mais closure, dois assuntos que você já viu. Se esse esqueleto ficou claro, o resto do módulo é aprender formas mais elegantes e completas de escrever a mesma coisa.
Teste rápido
O que a função com_moldura(func) devolve?
Perguntas frequentes
- Preciso entender closure antes de decoradores?
- Ajuda muito. Um decorador é uma closure: a função interna wrapper lembra da função original recebida no parâmetro. Se a ideia de uma função interna que guarda variáveis da externa ainda confunde, vale revisar o módulo de funções avançadas antes de seguir para o símbolo @.
- Por que passamos a função sem os parênteses?
- Sem parênteses, você passa o objeto função; com parênteses, você executa a função e passa o resultado. O decorador precisa receber a função em si para poder chamá-la mais tarde, dentro do wrapper. Por isso escrevemos com_moldura(dizer_ola), não com_moldura(dizer_ola()).
- O decorador altera a função original?
- Não. A função original continua intacta. O decorador cria uma função nova (o wrapper) que envolve a original e adiciona comportamento. O que muda é para onde o nome passa a apontar quando você reatribui, algo que a próxima aula formaliza com o símbolo @.
- Isso é a mesma coisa que decorador do padrão de projeto?
- A ideia é parecida (envolver algo para acrescentar comportamento), mas o decorador do Python é um recurso concreto da linguagem, com sintaxe própria. Neste curso tratamos do decorador do Python, aquele que você aplica com o símbolo @ sobre uma função.
- Todo decorador precisa de uma função interna?
- No padrão que você vai usar quase sempre, sim: a função externa recebe a função a decorar e a interna (o wrapper) faz o trabalho de envolvê-la. Existem variações mais avançadas, mas comece dominando esse formato de função dentro de função, que resolve a grande maioria dos casos.
- Function é objeto mesmo em Python?
- Sim. Funções são objetos de primeira classe: você pode guardá-las em variáveis, colocá-las em listas, passá-las como argumento e devolvê-las de outra função. Toda a mecânica de decoradores depende disso, e é por isso que a aula começa reforçando esse ponto.
Fontes
Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.