Декораторы в Python: Руководство для начинающих

RedDeveloper
31.12.2022 14:00
Декораторы в Python: Руководство для начинающих
Photo by Austin Distel on Unsplash

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

Как украсить функцию?

Одно из основных применений декораторов - добавление дополнительной функциональности к функции без изменения кода исходной функции. Это может быть полезно, когда вы хотите добавить логирование, кэширование или другие виды функциональности в функцию без изменения ее кода.

Чтобы создать декоратор в Python, нужно использовать символ @, за которым следует имя функции-декоратора. Например, допустим, у нас есть функция add, которая принимает два аргумента и возвращает их сумму:

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

Мы можем создать функцию-декоратор под названием log_function, которая записывает в журнал аргументы и возвращаемое значение функции add:

def log_function(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        print(f"Function {func.__name__} called with arguments {args} and keyword arguments {kwargs} returned {result}")
        return result
    return wrapper

Чтобы применить декоратор к функции add, мы просто используем символ @, за которым следует имя функции-декоратора:

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

Теперь при каждом вызове функции add будет применяться декоратор log_function, а аргументы и возвращаемое значение функции add будут записываться в журнал.

XY- 7-WZ
result = add(1, 2)

В результате будет выведено следующее сообщение:

Function add called with arguments (1, 2) and keyword arguments {} returned 3

Изменение поведения с помощью декораторов

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

def cache(func):
    cache = {}
    def wrapper(*args, **kwargs):
        key = f"{args}{kwargs}"
        if key in cache:
            return cache[key]
        result = func(*args, **kwargs)
        cache[key] = result
        return result
    return wrapper

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

Теперь при первом вызове функции add с определенным набором аргументов она вычислит и вернет результат. Если функция add будет вызвана с теми же аргументами еще раз, она вернет кэшированный результат вместо того, чтобы вычислять его снова.

Общие шаблоны с декораторами

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

Мы можем создать декоратор timeit, который будет измерять время выполнения функции и выводить его на консоль:

import time

def timeit(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"Function {func.__name__} took {end - start} seconds to execute")
        return result
    return wrapper

@timeit
def sum_list(numbers):
    result = 0
    for number in numbers:
        result += number
    return result

Теперь, когда мы вызываем функцию sum_list, она будет не только вычислять сумму чисел, но и выводить время выполнения на консоль:

result = sum_list([1, 2, 3, 4, 5])

В результате будет выведено следующее сообщение:

Function sum_list took 0.000001 seconds to execute

Заключение

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

Еженедельник новостей для разработчиков - выпуск №10
Еженедельник новостей для разработчиков - выпуск №10

04.02.2023 09:32

В выпуске этой недели собраны самые интересные статьи и новости, отобранные из всего контента, опубликованного за предыдущую неделю на сайте Developers News .

Как настроить Tailwind CSS с React.js и Next.js?
Как настроить Tailwind CSS с React.js и Next.js?

03.02.2023 09:34

Tailwind CSS - единственный фреймворк, который, как я убедился, масштабируется в больших командах. Он легко настраивается, адаптируется к любому дизайну, а размер сборки просто крошечный.

LeetCode запись решения 2536. Увеличение подматриц на единицу
LeetCode запись решения 2536. Увеличение подматриц на единицу

03.02.2023 08:15

Увеличение подматриц на единицу - LeetCode

Переключение светлых/темных тем
Переключение светлых/темных тем

02.02.2023 09:04

В Microsoft Training - Guided Project - Build a simple website with web pages, CSS files and JavaScript files, мы объясняем, как CSS можно использовать для установки светлых/темных стилей и добавления интерактивных функций с помощью JavaScript. Следуйте инструкциям, и вы готовы к работе!

Отношения "многие ко многим" в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel с методами присоединения и отсоединения

02.02.2023 07:39

Отношения "многие ко многим" в Laravel могут быть немного сложными, но с помощью Eloquent ORM и его моделей мы можем сделать это с легкостью. В этой статье мы расскажем, как создавать и управлять отношениями "многие ко многим" в Laravel с помощью методов присоединения и отсоединения вместо...

В PHP
В PHP

02.02.2023 07:16

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