Python
Декораторы
PythonКлассы-декораторы в Python
Основные концепции
1. Базовый класс-декоратор
class SimpleDecorator:
def __init__(self, func):
self.func = func # Сохраняем декорируемую функцию
def __call__(self, *args, **kwargs):
print("Действие перед вызовом функции")
result = self.func(*args, **kwargs)
print("Действие после вызова функции")
return result
@SimpleDecorator
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
2. Декоратор с параметрами
class ParametrizedDecorator:
def __init__(self, prefix=""):
self.prefix = prefix # Параметр декоратора
def __call__(self, func):
def wrapper(*args, **kwargs):
print(f"{self.prefix} Перед вызовом")
result = func(*args, **kwargs)
print(f"{self.prefix} После вызова")
return result
return wrapper
@ParametrizedDecorator(prefix="DEBUG:")
def calculate(a, b):
return a + b
print(calculate(2, 3))
3. Сохранение метаданных функции
import functools
class MetadataPreservingDecorator:
def __init__(self, func):
self.func = func
functools.wraps(func)(self) # Сохраняем метаданные
def __call__(self, *args, **kwargs):
"""Документация декоратора"""
print("Дополнительная логика")
return self.func(*args, **kwargs)
@MetadataPreservingDecorator
def example():
"""Оригинальная документация"""
print("Функция выполнена")
print(example.__name__) # example
print(example.__doc__) # Оригинальная документация
Продвинутые техники
4. Декоратор методов класса
class MethodDecorator:
def __init__(self, func):
self.func = func
def __call__(self, instance, *args, **kwargs):
print(f"Вызов метода {self.func.__name__} класса {instance.__class__.__name__}")
return self.func(instance, *args, **kwargs)
class MyClass:
@MethodDecorator
def my_method(self):
print("Метод выполнен")
obj = MyClass()
obj.my_method()
5. Декоратор с состоянием
class CounterDecorator:
def __init__(self, func):
self.func = func
self.calls = 0
def __call__(self, *args, **kwargs):
self.calls += 1
print(f"Функция вызвана {self.calls} раз")
return self.func(*args, **kwargs)
@CounterDecorator
def say_hello():
print("Hello!")
say_hello()
say_hello()
6. Декоратор с возможностью отключения
class SwitchableDecorator:
def __init__(self, active=True):
self.active = active
def __call__(self, func):
def wrapper(*args, **kwargs):
if self.active:
print("Декоратор активен")
return func(*args, **kwargs)
return wrapper
@SwitchableDecorator(active=False)
def function():
print("Функция выполнена")
function()
Важные моменты для собеседования
-
Как работает декоратор?
- Декоратор - это функция или класс, который принимает функцию и возвращает новую функцию
- Синтаксис @decorator эквивалентен func = decorator(func)
-
Разница между функцией-декоратором и классом-декоратором
- Классы-декораторы полезны, когда нужно:
- Сохранять состояние между вызовами
- Реализовать сложную логику
- Использовать ООП подход
- Классы-декораторы полезны, когда нужно:
-
Почему functools.wraps важен?
- Сохраняет оригинальное имя функции и документацию
- Без него декорированная функция теряет свои метаданные
-
Когда использовать классы-декораторы?
- Когда нужен декоратор с состоянием
- Для сложных декораторов с несколькими уровнями вложенности
- Когда требуется повторно используемая логика декорирования
Асинхронный парсер
PythonНе так давно для одного небольшого проекта возникла необходимость пропарсить большое количество страниц, получить необходимую информацию и выгрузить изображения. Как раз в таких ситуациях, где быстро необходимо получить информацию из разных источников приходит на помощь асинхронность. В Python это реализуется очень просто.

Flask SQLAlchemy: Разбивка на страницы
PythonЕсли вы используете Flask SQLAlchemy, то у вас есть замечательная возможность делать пагинацию - разбивку на страницы для удобной навигации между записями. Делается это очень просто, буквально в несколько строк кода. Я расскажу как это реализовано в моем блоге в упрощенном виде, с использованием двух ссылок и вариант с нумерацией страниц.

Установка пакетов Python без подключения к интернету
PythonИногда необходимо установить пакеты Python на устройство без доступа к интернету, например, в закрытых средах. В этом случае нужно предварительно скачать необходимые пакеты на устройство с подключением к сети, а затем установить их офлайн. Этот метод позволяет установить все необходимые зависимости, скачанные предварительно на устройство с подключением к интернету.

AJAX + FLASK
PythonИногда необходимо выполнить определенные действия без обновления страницы - авторизоваться на сайте или поставить лайк. AJAX позволяет выполнить эти действия без особых проблем. В этой небольшой статье я расскажу как можно выполнить авторизацию на сайте без обновления страницы во Flask.
