CodeGym /Kursy /Python SELF PL /Cała moc dekoratorów

Cała moc dekoratorów

Python SELF PL
Poziom 14 , Lekcja 2
Dostępny

6.1 Dekoratory metod klas

Dekoratory mogą być również używane do metod klas. Ważne jest, aby pamiętać, że dla metod klas należy poprawnie przekazywać argumenty self lub cls.

Niestety nie omawialiśmy jeszcze szczegółów działania klas, ale chcielibyśmy, abyście wiedzieli, że dekoratory mają taką możliwość.


def log_method_call(func):
    def wrapper(self, *args, **kwargs):
        print(f"Wywołanie metody {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()

Wyjaśnienie

Dekorator (log_method_call): Ten dekorator przyjmuje metodę func i zwraca nową funkcję wrapper, która wyświetla komunikat przed wywołaniem metody.

Metoda klasy z dekoratorem (say_hello): Metoda say_hello jest opakowana w dekorator log_method_call, co dodaje dodatkowe zachowanie podczas jej wywołania.

Wynik:


Wywołanie metody say_hello
Hello from MyClass!

6.2 Kilka dekoratorów

Możesz używać kilku dekoratorów dla jednej funkcji, nakładając je na siebie. Dekoratory stosuje się w odwrotnej kolejności niż są zadeklarowane.


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

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

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

Wyjaśnienie

Dekoratory (decorator1 i decorator2): Te dekoratory dodają swoje komunikaty przed wywołaniem funkcji func.

Funkcja z dekoratorami (say_hello): Funkcja say_hello jest opakowana w oba dekoratory. Najpierw zastosowany jest decorator2, potem decorator1.

Wynik:


# Dekorator 1
# Dekorator 2
Hello!

6.3 Wbudowane dekoratory

Python udostępnia kilka wbudowanych dekoratorów do standardowych zadań, takich jak metody statyczne, metody klasowe i właściwości.

@staticmethod

Dekorator @staticmethod jest używany do tworzenia metody statycznej, która nie wymaga instancji klasy do jej wywołania.


class MyClass:
    @staticmethod
    def static_method():
        print("To jest metoda statyczna.")
        
MyClass.static_method()

@classmethod

Dekorator @classmethod jest używany do tworzenia metody klasowej, która przyjmuje klasę (a nie instancję) jako pierwszy argument.


class MyClass:
    @classmethod
    def class_method(cls):
        print(f"To jest metoda klasy {cls.__name__}.")
        
MyClass.class_method()

@property

Dekorator @property jest używany do tworzenia getterów, setterów i deleterów dla atrybutów.


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

To są wbudowane dekoratory, a ich poprawne działanie zapewnia sam interpreter Pythona.

6.4 Przykłady użycia dekoratorów

Logowanie

Dekoratory mogą być używane do logowania wywołań funkcji i metod.


def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"Wywołanie funkcji {func.__name__} z argumentami {args} i {kwargs}")
        return func(*args, **kwargs)

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

Kontrola dostępu

Dekoratory mogą być używane do kontroli dostępu do funkcji i metod.


def require_authentication(func):
    def wrapper(*args, **kwargs):
        if not args[0].is_authenticated:
            raise PermissionError("Użytkownik nie jest uwierzytelniony.")
        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("Profil użytkownika")
        
user = User(is_authenticated=True)
user.view_profile()  # Pomyślne wywołanie
        
user2 = User(is_authenticated=False)
user2.view_profile()  # PermissionError: Użytkownik nie jest uwierzytelniony.

Buforowanie

Dekoratory mogą być używane do buforowania wyników funkcji.


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