Decoradores são uma das características mais elegantes e poderosas de Python. Eles permitem modificar o comportamento de funções ou métodos sem alterar o código da função em si. Decoradores são amplamente utilizados para adicionar funcionalidades, realizar verificações ou até mesmo para modificar a interface de uma função. Vamos mergulhar neste conceito e ver como podemos utilizá-los de maneira prática.
Conceito Básico
Um decorador em Python é, basicamente, uma função que recebe outra função como argumento e devolve uma nova função. Isso permite "decorar" ou adicionar funcionalidades à função original.
Estrutura Básica de um Decorador
Vamos criar um decorador simples que imprime uma mensagem antes e depois de chamar a função original.
def meu_decorador(funcao):
def wrapper():
print("Algo a fazer antes de executar a função.")
funcao()
print("Algo a fazer depois de executar a função.")
return wrapper
Agora, podemos usar este decorador para decorar qualquer função. Por exemplo:
@meu_decorador
def diga_ola():
print("Olá!")
diga_ola()
A saída será:
Algo a fazer antes de executar a função.
Olá!
Algo a fazer depois de executar a função.
Decoradores com Argumentos
Frequentemente, as funções que queremos decorar têm argumentos. Vamos modificar nosso decorador para aceitar qualquer número de argumentos e parâmetros.
def meu_decorador(funcao):
def wrapper(*args, **kwargs):
print("Algo a fazer antes de executar a função.")
resultado = funcao(*args, **kwargs)
print("Algo a fazer depois de executar a função.")
return resultado
return wrapper
Agora, vamos decorar uma função com argumentos:
@meu_decorador
def soma(a, b):
return a + b
resultado = soma(5, 3)
print("Resultado:", resultado)
A saída agora será:
Algo a fazer antes de executar a função.
Algo a fazer depois de executar a função.
Resultado: 8
Decoradores na Vida Real
Vamos explorar alguns exemplos práticos onde decoradores são usados no dia-a-dia dos programadores.
Temporização de Funções
Imagine que quer medir quanto tempo uma função demora a executar. Um decorador é uma excelente maneira de o fazer.
import time
def temporizador(funcao):
def wrapper(*args, **kwargs):
inicio = time.time()
resultado = funcao(*args, **kwargs)
fim = time.time()
print(f"Tempo de execução: {fim - inicio:.4f} segundos")
return resultado
return wrapper
@temporizador
def soma_lenta(a, b):
time.sleep(2)
return a + b
resultado = soma_lenta(5, 3)
print("Resultado:", resultado)
A saída será algo como:
Tempo de execução: 2.0024 segundos
Resultado: 8
Verificação de Permissões
Suponhamos que temos diferentes níveis de permissão para executar certas funções. Podemos criar um decorador para verificar permissões antes de executar a função.
def verifica_permissao(nivel_necessario):
def decorador(funcao):
def wrapper(*args, **kwargs):
if args[0] < nivel_necessario:
print("Permissão negada")
return None
return funcao(*args, **kwargs)
return wrapper
return decorador
@verifica_permissao(3)
def funcao_sensivel(nivel):
print("Execução de uma função sensível")
nivel_utilizador = 2
funcao_sensivel(nivel_utilizador)
nivel_utilizador = 4
funcao_sensivel(nivel_utilizador)
A saída será:
Permissão negada
Execução de uma função sensível
Resumo
Os decoradores são uma ferramenta poderosa que permite adicionar ou modificar funcionalidades de funções de uma maneira eficiente e elegante. Eles são particularmente úteis para adicionar verificações, temporizações, ou outras funcionalidades transversais sem modificar diretamente o código original da função.
Quiz
Teste os seus conhecimentos sobre decoradores com as seguintes perguntas:
- O que é um decorador em Python?
- Como se define um decorador que aceita argumentos?
- Em que situações práticas podes usar decoradores?
- Escreva um decorador que imprime "Início" e "Fim" antes e depois de executar uma função.
- Como podemos utilizar decoradores para verificar permissões de utilizador antes de executar uma função?
Responder estas questões ajudará a consolidar o seu entendimento sobre decoradores em Python.