Em Python, os decoradores são uma característica poderosa e versátil da linguagem que permite adicionar funcionalidades a funções e métodos existentes de uma forma concisa e elegante. Eles são amplamente utilizados em Python para modificar ou aprimorar o comportamento de funções ou métodos sem a necessidade de modificar seu código subjacente.
Um decorador em Python é, essencialmente, uma função que aceita outra função como argumento e retorna uma nova função com algumas alterações ou aprimoramentos. Isso permite que os decoradores envolvam, modificem ou estendam a funcionalidade da função original sem modificar seu código interno.
A sintaxe básica de um decorador em Python envolve o uso do símbolo @ seguido pelo nome do decorador acima da definição da função que será decorada. Por exemplo:
python@decorador
def funcao_decorada():
# corpo da função
pass
A função decorador é então chamada com a função funcao_decorada como argumento, e o resultado é atribuído à própria funcao_decorada, substituindo-a efetivamente.
Existem várias aplicações práticas para o uso de decoradores em Python, incluindo:
-
Log de execução: Os decoradores podem ser usados para adicionar lógica de registro a funções ou métodos, registrando informações como o tempo de execução, os argumentos passados e os valores de retorno.
-
Autenticação e autorização: Decoradores podem ser usados para verificar se um usuário possui permissões adequadas para acessar uma determinada função ou método.
-
Memorização (caching): Os decoradores podem ser utilizados para armazenar em cache o resultado de chamadas de função com argumentos específicos, economizando tempo de computação quando a mesma chamada é feita repetidamente.
-
Validação de entrada: Decoradores podem ser empregados para verificar a validade dos argumentos passados para uma função, ajudando a garantir que apenas dados válidos sejam processados.
-
Temporização: Os decoradores podem ser usados para medir o tempo de execução de uma função e impor limites de tempo de execução.
Um exemplo simples de um decorador em Python é o seguinte:
pythondef meu_decorador(funcao):
def wrapper():
print("Antes da execução da função")
funcao()
print("Depois da execução da função")
return wrapper
@meu_decorador
def minha_funcao():
print("Minha função sendo executada")
minha_funcao()
Neste exemplo, o decorador meu_decorador adiciona lógica de impressão antes e depois da execução da função minha_funcao. Quando minha_funcao é chamada, ela é na verdade substituída pela função wrapper retornada pelo decorador.
Decoradores também podem aceitar argumentos, permitindo uma maior flexibilidade e personalização. Por exemplo:
pythondef decorador_com_argumento(arg1, arg2):
def decorador(funcao):
def wrapper(*args, **kwargs):
print("Argumentos do decorador:", arg1, arg2)
funcao(*args, **kwargs)
return wrapper
return decorador
@decorador_com_argumento("ola", 42)
def funcao_decorada_com_argumento(msg):
print(msg)
funcao_decorada_com_argumento("Olá, mundo!")
Neste caso, o decorador decorador_com_argumento aceita dois argumentos arg1 e arg2, que são então passados para o decorador interno que envolve a função decorada. Quando funcao_decorada_com_argumento é chamada, os argumentos do decorador são impressos junto com a mensagem passada.
Em resumo, os decoradores são uma ferramenta poderosa em Python que permite adicionar funcionalidades de forma transparente e modular a funções e métodos existentes. Eles são amplamente utilizados em muitas bibliotecas e frameworks Python para implementar recursos avançados, como autenticação, registro e validação de entrada. Dominar o uso de decoradores pode levar a um código mais limpo, modular e eficiente em Python.
“Mais Informações”

Claro! Vamos explorar mais a fundo o conceito de decoradores em Python e algumas de suas aplicações comuns.
-
Encadeamento de Decoradores:
Em Python, é possível encadear múltiplos decoradores em uma única função. Isso significa que você pode aplicar vários decoradores a uma função, um após o outro, para adicionar diferentes funcionalidades. Por exemplo:pythondef decorador1(funcao): def wrapper(): print("Antes da execução do decorador 1") funcao() print("Depois da execução do decorador 1") return wrapper def decorador2(funcao): def wrapper(): print("Antes da execução do decorador 2") funcao() print("Depois da execução do decorador 2") return wrapper @decorador1 @decorador2 def minha_funcao(): print("Minha função sendo executada") minha_funcao()Neste exemplo,
minha_funcaoé primeiro decorada pelodecorador2e, em seguida, pelodecorador1. Portanto, a ordem de execução dos decoradores é de dentro para fora, ou seja, odecorador2é executado primeiro, seguido pelodecorador1. -
Usando Argumentos em Decoradores:
Como mencionado anteriormente, os decoradores podem aceitar argumentos. Isso permite uma personalização mais detalhada do comportamento do decorador. Por exemplo, um decorador que controla o nível de log com base em um argumento:pythondef log_nivel(nivel): def decorador(funcao): def wrapper(*args, **kwargs): if nivel == "debug": print("DEBUG:", funcao.__name__, "foi chamada") elif nivel == "info": print("INFO:", funcao.__name__, "foi chamada") elif nivel == "error": print("ERROR:", funcao.__name__, "foi chamada") return funcao(*args, **kwargs) return wrapper return decorador @log_nivel("debug") def minha_funcao(): print("Executando minha função") minha_funcao()Neste exemplo, o decorador
log_nivelaceita um argumentonivel, que determina o nível de log a ser exibido. Dependendo do valor do argumentonivel, uma mensagem de log diferente é exibida antes da execução da função decorada. -
Decoradores de Classe:
Além de decorar funções, é possível também decorar métodos de classe em Python. Isso é útil em situações onde se deseja adicionar funcionalidades a métodos específicos de uma classe. A sintaxe para decoradores de método é semelhante à dos decoradores de função, mas o primeiro argumento do método decorado é a própria instância da classe (self). Por exemplo:pythondef decorador_de_metodo(funcao): def wrapper(self): print("Antes da execução do método") funcao(self) print("Depois da execução do método") return wrapper class MinhaClasse: @decorador_de_metodo def meu_metodo(self): print("Executando meu método") obj = MinhaClasse() obj.meu_metodo()Aqui, o método
meu_metododa classeMinhaClasseé decorado pelodecorador_de_metodo, que adiciona lógica de impressão antes e depois da execução do método. -
Decoradores como Classes:
Embora a abordagem tradicional de decoradores envolva o uso de funções, em Python é possível implementar decoradores usando classes. Decoradores de classe têm a vantagem de encapsular estado, permitindo uma personalização mais avançada. Por exemplo:pythonclass MeuDecorador: def __init__(self, funcao): self.funcao = funcao def __call__(self, *args, **kwargs): print("Antes da execução da função") resultado = self.funcao(*args, **kwargs) print("Depois da execução da função") return resultado @MeuDecorador def minha_funcao(): print("Executando minha função") minha_funcao()Neste exemplo,
MeuDecoradoré uma classe que age como um decorador. Ela implementa o método__call__, que permite que a instância da classe seja chamada como uma função. Dentro de__call__, a lógica de impressão é adicionada antes e depois da execução da função decorada. -
Decoradores embutidos:
Python possui alguns decoradores embutidos, que são comumente usados para certos fins. Alguns exemplos incluem:@staticmethod: Transforma um método em um método estático, que pode ser chamado na classe sem criar uma instância.@classmethod: Transforma um método em um método de classe, que recebe a própria classe como argumento em vez de uma instância.@property: Permite que um método seja acessado como um atributo, sem a necessidade de chamá-lo explicitamente.
Em resumo, os decoradores em Python são uma ferramenta poderosa para adicionar funcionalidades dinâmicas e reutilizáveis a funções e métodos. Eles oferecem uma maneira elegante de estender o comportamento de código existente sem a necessidade de modificá-lo diretamente. Ao compreender os conceitos e padrões de uso dos decoradores, os desenvolvedores podem escrever código Python mais modular, flexível e fácil de manter.

