6.1 Декоратори для методів класів
Декоратори також можуть використовуватися для методів класів. Важливо пам'ятати, що для методів класів необхідно правильно передавати аргументи self або cls.
Нюанси роботи класів ми з вами ще не проходили, але хотілося б, щоб ви знали, що така можливість у декораторів є.
def log_method_call(func):
def wrapper(self, *args, **kwargs):
print(f"Виклик методу {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()
Пояснення
Декоратор (log_method_call): Цей декоратор приймає метод func і повертає нову функцію wrapper, яка виводить повідомлення перед викликом методу.
Метод класу з декоратором (say_hello): Метод say_hello обгорнутий декоратором log_method_call, що додає додаткову поведінку при його виклику.
Вивід:
Виклик методу say_hello
Hello from MyClass!
6.2 Декілька декораторів
Ви можете використовувати кілька декораторів для однієї функції, накладаючи їх один на одного. Декоратори застосовуються в порядку, зворотному їх оголошенню.
def decorator1(func):
def wrapper():
print("Декоратор 1")
func()
return wrapper
def decorator2(func):
def wrapper():
print("Декоратор 2")
func()
return wrapper
@decorator1
@decorator2
def say_hello():
print("Hello!")
say_hello()
Пояснення
Декоратори (decorator1 і decorator2): Ці декоратори додають свої повідомлення перед викликом функції func.
Функція з декораторами (say_hello): Функція say_hello обгорнута обома декораторами. Спочатку застосовується decorator2, потім decorator1.
Вивід:
# Декоратор 1
# Декоратор 2
Hello!
6.3 Вбудовані декоратори
Python надає кілька вбудованих декораторів для стандартних задач, таких як статичні методи, методи класу та властивості.
@staticmethod
Декоратор @staticmethod використовується для створення статичного методу, який не потребує екземпляра класу для виклику.
class MyClass:
@staticmethod
def static_method():
print("Це статичний метод.")
MyClass.static_method()
@classmethod
Декоратор @classmethod використовується для створення методу класу, який приймає клас (а не екземпляр) як перший аргумент.
class MyClass:
@classmethod
def class_method(cls):
print(f"Це метод класу {cls.__name__}.")
MyClass.class_method()
@property
Декоратор @property використовується для створення геттерів, сеттерів і делетерів для атрибутів.
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) # Вивід: 10
obj.value = 20
print(obj.value) # Вивід: 20
Це вбудовані декоратори, їх правильну роботу забезпечує сам інтерпретатор Python.
6.4 Приклади використання декораторів
Логування
Декоратори можуть бути використані для логування викликів функцій і методів.
def log_call(func):
def wrapper(*args, **kwargs):
print(f"Виклик функції {func.__name__} з аргументами {args} і {kwargs}")
return func(*args, **kwargs)
return wrapper
@log_call
def add(x, y):
return x + y
print(add(2, 3))
Контроль доступу
Декоратори можуть бути використані для контролю доступу до функцій і методів.
def require_authentication(func):
def wrapper(*args, **kwargs):
if not args[0].is_authenticated:
raise PermissionError("Користувач не аутентифікований.")
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("Профіль користувача")
user = User(is_authenticated=True)
user.view_profile() # Успішний виклик
user2 = User(is_authenticated=False)
user2.view_profile() # PermissionError: Користувач не аутентифікований.
Кешування
Декоратори можуть бути використані для кешування результатів функції.
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))
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ