CodeGym /Corsi /Python SELF IT /Tutta la potenza dei decoratori

Tutta la potenza dei decoratori

Python SELF IT
Livello 14 , Lezione 2
Disponibile

6.1 Decoratori per metodi di classe

I decoratori possono essere utilizzati anche per i metodi di classe. È importante ricordare di passare correttamente gli argomenti self o cls.

Non abbiamo ancora affrontato nei dettagli il funzionamento delle classi, ma vorrei che sapessi che i decoratori hanno questa capacità.


def log_method_call(func):
    def wrapper(self, *args, **kwargs):
        print(f"Chiamata al metodo {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()

Spiegazione

Decoratore (log_method_call): Questo decoratore accetta il metodo func e restituisce una nuova funzione wrapper, che stampa un messaggio prima di chiamare il metodo.

Metodo di classe con decoratore (say_hello): Il metodo say_hello è avvolto dal decoratore log_method_call, che aggiunge un comportamento aggiuntivo quando viene chiamato.

Output:


Chiamata al metodo say_hello
Hello from MyClass!

6.2 Più decoratori

Puoi utilizzare più decoratori su una singola funzione, applicandoli uno sopra l'altro. I decoratori vengono applicati in ordine inverso rispetto alla loro dichiarazione.


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

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

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

Spiegazione

Decoratori (decorator1 e decorator2): Questi decoratori aggiungono i loro messaggi prima di chiamare la funzione func.

Funzione con decoratori (say_hello): La funzione say_hello è avvolta da entrambi i decoratori. Prima viene applicato decorator2, poi decorator1.

Output:


# Decoratore 1
# Decoratore 2
Hello!

6.3 Decoratori integrati

Python fornisce diversi decoratori integrati per compiti standard, come metodi statici, metodi di classe e proprietà.

@staticmethod

Il decoratore @staticmethod è utilizzato per creare un metodo statico, che non richiede un'istanza della classe per essere chiamato.


class MyClass:
    @staticmethod
    def static_method():
        print("Questo è un metodo statico.")
        
MyClass.static_method()

@classmethod

Il decoratore @classmethod è utilizzato per creare un metodo di classe, che accetta la classe (anziché l'istanza) come primo argomento.


class MyClass:
    @classmethod
    def class_method(cls):
        print(f"Questo è un metodo di classe {cls.__name__}.")
        
MyClass.class_method()

@property

Il decoratore @property è utilizzato per creare getter, setter e deleter per gli attributi.


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)  # Output: 10
obj.value = 20
print(obj.value)  # Output: 20

Questi sono decoratori integrati, il loro corretto funzionamento è garantito dall'interprete di Python.

6.4 Esempi di utilizzo dei decoratori

Logging

I decoratori possono essere utilizzati per loggare le chiamate a funzioni e metodi.


def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"Chiamata alla funzione {func.__name__} con argomenti {args} e {kwargs}")
        return func(*args, **kwargs)

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

Controllo dell'accesso

I decoratori possono essere utilizzati per controllare l'accesso a funzioni e metodi.


def require_authentication(func):
    def wrapper(*args, **kwargs):
        if not args[0].is_authenticated:
            raise PermissionError("Utente non autenticato.")
        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("Profilo utente")
        
user = User(is_authenticated=True)
user.view_profile()  # Chiamata riuscita
        
user2 = User(is_authenticated=False)
user2.view_profile()  # PermissionError: Utente non autenticato.

Caching

I decoratori possono essere utilizzati per memorizzare i risultati di una funzione.


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))
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION