Programador Leigo
Python 10 min leitura 05 MAR 2026

Decorators em Python: o que são e como criar o seu

Entenda de verdade como funciona a mágica por trás do @login_required.


O que é um decorator?

Um decorator é uma função que recebe outra função como argumento e retorna uma nova função com comportamento adicional. Em Python, usamos o símbolo @ como atalho sintático para aplicar decorators.

Na prática, quando você escreve:

@meu_decorator
def minha_funcao():
    pass

O Python está fazendo isso por baixo dos panos:

minha_funcao = meu_decorator(minha_funcao)

Funções são objetos

Para entender decorators, você precisa saber que funções em Python são objetos de primeira classe. Isso significa que você pode passar funções como argumentos, retorná-las de outras funções e atribuí-las a variáveis.

def saudacao(nome):
    return f"Ola, {nome}!"

# Atribuindo a funcao a uma variavel
cumprimento = saudacao
print(cumprimento("Maria"))  # Ola, Maria!

# Passando como argumento
def executar(funcao, valor):
    return funcao(valor)

print(executar(saudacao, "Joao"))  # Ola, Joao!

Criando seu primeiro decorator

Vamos criar um decorator que mede o tempo de execução de uma função:

import time
from functools import wraps

def medir_tempo(funcao):
    @wraps(funcao)
    def wrapper(*args, **kwargs):
        inicio = time.time()
        resultado = funcao(*args, **kwargs)
        fim = time.time()
        print(f"{funcao.__name__} executou em {fim - inicio:.4f}s")
        return resultado
    return wrapper

@medir_tempo
def buscar_dados():
    time.sleep(1)
    return {"status": "ok"}

buscar_dados()
# buscar_dados executou em 1.0012s

O @wraps(funcao) é importante porque preserva o nome e a docstring da função original. Sem ele, buscar_dados.__name__ retornaria "wrapper" em vez de "buscar_dados".

Decorators com argumentos

Quando o decorator precisa receber parâmetros, você adiciona mais uma camada de função:

from functools import wraps

def repetir(vezes):
    def decorator(funcao):
        @wraps(funcao)
        def wrapper(*args, **kwargs):
            for _ in range(vezes):
                resultado = funcao(*args, **kwargs)
            return resultado
        return wrapper
    return decorator

@repetir(vezes=3)
def dizer_ola():
    print("Ola!")

dizer_ola()
# Ola!
# Ola!
# Ola!

Como funciona o @login_required

Agora que você entende decorators, fica fácil compreender o @login_required do Flask-Login. Ele segue a mesma lógica:

from functools import wraps
from flask import redirect, url_for
from flask_login import current_user

def login_required(funcao):
    @wraps(funcao)
    def wrapper(*args, **kwargs):
        if not current_user.is_authenticated:
            return redirect(url_for("login"))
        return funcao(*args, **kwargs)
    return wrapper

Antes de executar a função da rota, o decorator verifica se o usuário está autenticado. Se não estiver, redireciona para a página de login. Caso contrário, a função original é executada normalmente.

Exemplo prático: decorator de permissão

Vamos criar um decorator que verifica se o usuário tem uma permissão específica:

from functools import wraps
from flask import abort
from flask_login import current_user

def requer_permissao(permissao):
    def decorator(funcao):
        @wraps(funcao)
        def wrapper(*args, **kwargs):
            if not current_user.tem_permissao(permissao):
                abort(403)
            return funcao(*args, **kwargs)
        return wrapper
    return decorator

@app.route("/admin")
@login_required
@requer_permissao("admin")
def painel_admin():
    return render_template("admin.html")

Conclusão

Decorators são uma ferramenta poderosa do Python que permite adicionar comportamento a funções sem modificar seu código. Eles estão por toda parte: no Flask, no Django, em bibliotecas de teste e muito mais. Dominar esse conceito vai te ajudar a escrever código mais limpo e reutilizável.

Continue lendo

Compartilhar