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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?

20.08.2023 18:21

Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в 2023-2024 годах? Или это полная лажа?".

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией

20.08.2023 17:46

В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox

19.08.2023 18:39

Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в частности, магию поплавков и гибкость flexbox.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest

19.08.2023 17:22

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

Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️

18.08.2023 20:33

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL

14.08.2023 14:49

Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип предназначен для представления неделимого значения.