CodeGym /Curso Java /Python SELF PT /Todo o poder dos decoradores

Todo o poder dos decoradores

Python SELF PT
Nível 14 , Lição 2
Disponível

6.1 Decoradores para métodos de classe

Decoradores também podem ser usados para métodos de classes. É importante lembrar que para métodos de classe é necessário passar os argumentos self ou cls corretamente.

Nós ainda não vimos detalhes sobre classes, mas gostaria que você soubesse que essa possibilidade existe para decoradores.


def log_method_call(func):
    def wrapper(self, *args, **kwargs):
        print(f"Chamada do método {func.__name__}")
        return func(self, *args, **kwargs)

    return wrapper
        
class MyClass:
    @log_method_call
    def say_hello(self):
        print("Hello from MyClass!")
        
obj = MyClass()
obj.say_hello()

Explicação

Decorador (log_method_call): Este decorador aceita o método func e retorna uma nova função wrapper, que exibe uma mensagem antes da chamada do método.

Método de classe com decorador (say_hello): O método say_hello está envolvido pelo decorador log_method_call, que adiciona comportamento extra quando ele é chamado.

Saída:


Chamada do método say_hello
Hello from MyClass!

6.2 Vários decoradores

Você pode usar vários decoradores para uma única função, empilhando eles. Os decoradores são aplicados na ordem inversa à sua declaração.


def decorator1(func):
    def wrapper():
        print("Decorador 1")
        func()

    return wrapper
        
def decorator2(func):
    def wrapper():
        print("Decorador 2")
        func()

    return wrapper
        
@decorator1
@decorator2
def say_hello():
    print("Hello!")
        
say_hello()

Explicação

Decoradores (decorator1 e decorator2): Esses decoradores adicionam suas mensagens antes da chamada da função func.

Função com decoradores (say_hello): A função say_hello está envolvida por ambos os decoradores. Primeiro decorator2 é aplicado, em seguida decorator1.

Saída:


# Decorador 1
# Decorador 2
Hello!

6.3 Decoradores embutidos

Python fornece diversos decoradores embutidos para tarefas padrão, como métodos estáticos, métodos de classe e propriedades.

@staticmethod

O decorador @staticmethod é usado para criar um método estático, que não requer uma instância da classe para ser chamado.


class MyClass:
    @staticmethod
    def static_method():
        print("Este é um método estático.")
        
MyClass.static_method()

@classmethod

O decorador @classmethod é usado para criar um método de classe, que aceita a classe (ao invés de uma instância) como o primeiro argumento.


class MyClass:
    @classmethod
    def class_method(cls):
        print(f"Este é um método da classe {cls.__name__}.")
        
MyClass.class_method()

@property

O decorador @property é usado para criar getters, setters e deleters para atributos.


class MyClass:
    def __init__(self, value):
        self.hidden_value = value
        
    @property
    def value(self):
        return self.hidden_value
        
    @value.setter
    def value(self, new_value):
        self.hidden_value = new_value
        
obj = MyClass(10)
print(obj.value)  # Saída: 10
obj.value = 20
print(obj.value)  # Saída: 20

Estes são decoradores embutidos, seu funcionamento correto é garantido pelo próprio interpretador Python.

6.4 Exemplos de uso de decoradores

Log

Decoradores podem ser usados para registrar chamadas de funções e métodos.


def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"Chamada da função {func.__name__} com argumentos {args} e {kwargs}")
        return func(*args, **kwargs)

    return wrapper
        
@log_call
def add(x, y):
    return x + y
        
print(add(2, 3))

Controle de acesso

Decoradores podem ser usados para controlar o acesso a funções e métodos.


def require_authentication(func):
    def wrapper(*args, **kwargs):
        if not args[0].is_authenticated:
            raise PermissionError("Usuário não autenticado.")
        return func(*args, **kwargs)
        
    return wrapper
        
class User:
    def __init__(self, is_authenticated):
        self.is_authenticated = is_authenticated
        
    @require_authentication
    def view_profile(self):
        print("Perfil do usuário")
        
user = User(is_authenticated=True)
user.view_profile()  # Chamada bem-sucedida
        
user2 = User(is_authenticated=False)
user2.view_profile()  # PermissionError: Usuário não autenticado.

Cache

Decoradores podem ser usados para armazenar em cache os resultados de uma função.


def cache(func):
    cached_results = {}

    def wrapper(*args):
        if args in cached_results:
            return cached_results[args]
        result = func(*args)
        cached_results[args] = result
        return result

    return wrapper

@cache
def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(35))
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION