Декораторы в Python

Обложка к статье "Декораторы в Python"

Декораторы — это мощный инструмент в Python, позволяющий модифицировать или расширять поведение функций и методов без изменения их исходного кода. В этой статье мы подробно рассмотрим, что такое декораторы, как они работают, и приведем примеры их использования.

Введение в декораторы

Что такое декоратор?

Декоратор — это функция, которая принимает другую функцию в качестве аргумента, выполняет некоторые операции и возвращает новую функцию или объект. Декораторы часто используются для добавления функциональности к существующим функциям, таких как логирование, проверка прав доступа или кэширование.

Основы синтаксиса

Синтаксис декораторов в Python включает символ @, за которым следует имя декоратора, размещенное непосредственно перед объявлением функции:

@имя_декоратора
def функция():
    # тело функции

Этот синтаксис эквивалентен следующему:

def функция():
    # тело функции

функция = имя_декоратора(функция)

Пример создания простого декоратора

Рассмотрим простой пример создания декоратора, который выводит сообщение до и после выполнения функции:

def simple_decorator(func):
    def wrapper():
        print("До выполнения функции")
        func()
        print("После выполнения функции")
    return wrapper

@simple_decorator
def say_hello():
    print("Привет!")

say_hello()

В этом примере:

  • simple_decorator — это декоратор, который принимает функцию func в качестве аргумента.
  • wrapper — это внутренняя функция, которая выполняет дополнительные действия до и после вызова func.
  • say_hello — это декорируемая функция.

При вызове say_hello() вывод будет следующим:

До выполнения функции
Привет!
После выполнения функции

Декораторы с аргументами

Декораторы также могут работать с функциями, принимающими аргументы. Для этого необходимо изменить внутреннюю функцию wrapper так, чтобы она принимала произвольное количество аргументов и передавала их декорируемой функции:

def decorator_with_args(func):
    def wrapper(*args, **kwargs):
        print("До выполнения функции")
        result = func(*args, **kwargs)
        print("После выполнения функции")
        return result
    return wrapper

@decorator_with_args
def greet(name):
    print(f"Привет, {name}!")

greet("Алексей")

В этом примере:

  • wrapper принимает произвольное количество позиционных и именованных аргументов (*args и **kwargs).
  • Эти аргументы передаются декорируемой функции greet.

При вызове greet("Алексей") вывод будет следующим:

До выполнения функции
Привет, Алексей!
После выполнения функции

Применение нескольких декораторов

Python позволяет применять несколько декораторов к одной функции. Декораторы применяются в порядке, начиная с ближайшего к функции:

def decorator_one(func):
    def wrapper(*args, **kwargs):
        print("Вход в декоратор один")
        result = func(*args, **kwargs)
        print("Выход из декоратора один")
        return result
    return wrapper

def decorator_two(func):
    def wrapper(*args, **kwargs):
        print("Вход в декоратор два")
        result = func(*args, **kwargs)
        print("Выход из декоратора два")
        return result
    return wrapper

@decorator_one
@decorator_two
def say_hello():
    print("Привет!")

say_hello()

Вывод будет следующим:

Вход в декоратор один
Вход в декоратор два
Привет!
Выход из декоратора два
Выход из декоратора один

Полезные примеры использования декораторов

Логирование

Декораторы часто используются для логирования выполнения функций:

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Вызов функции {func.__name__} с аргументами {args} и {kwargs}")
        result = func(*args, **kwargs)
        print(f"Функция {func.__name__} вернула {result}")
        return result
    return wrapper

@log_decorator
def add(a, b):
    return a + b

add(3, 5)

В этом примере:

  • Декоратор log_decorator выводит информацию о вызове функции add, ее аргументах и возвращаемом значении.

Проверка прав доступа

Декораторы могут использоваться для проверки прав доступа:

def require_auth(func):
    def wrapper(*args, **kwargs):
        user = kwargs.get('user')
        if not user or not user.get('is_authenticated'):
            print("Доступ запрещен")
            return
        return func(*args, **kwargs)
    return wrapper

@require_auth
def view_dashboard(user):
    print("Добро пожаловать на панель управления!")

view_dashboard(user={'is_authenticated': True})
view_dashboard(user={'is_authenticated': False})

В этом примере:

  • Декоратор require_auth проверяет, аутентифицирован ли пользователь, и разрешает или запрещает доступ к функции view_dashboard.
Оцените статью
( Пока оценок нет )
Обучение Python
Добавить комментарий