Найти в Дзене

Декораторы в Python: простые решения для сложных задач

Привет! Сегодня расскажу про декораторы и почему они делают код лучше. Декоратор — это специальная функция, которая позволяет изменять или расширять поведение другой функции или метода без изменения ее кода. Декораторы еще называют функциями высшего порядка, так как они принимают функцию как аргумент, и возвращают тоже функцию. Напишем простой декоратор, который любой вывод функции оборачивает знаками "@@...@@". Разберем последовательность выполнения такого декоратора. 1. При старте quote_decorator(say_hello) вначале сработает строка 5, произойдет вызов функции wrapper. 2. Внутри функции wrapper произойдет вызов func(), но это результат будет преобразован: добавится "обертка" в виде кавычек и собачек. Хотя использование декоратора без @ работает, в Python существует более удобный способ применения декораторов с помощью символа @. Это позволяет сделать код более читаемым и понятным. Последовательность вызовов при этом "под капотом" останется прежней: сначала вызовется функция qoute_de
Оглавление

Привет! Сегодня расскажу про декораторы и почему они делают код лучше.

Декораторы

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

Декораторы еще называют функциями высшего порядка, так как они принимают функцию как аргумент, и возвращают тоже функцию.

Что делает декоратор в Python

Напишем простой декоратор, который любой вывод функции оборачивает знаками "@@...@@".

-2

Разберем последовательность выполнения такого декоратора.

1. При старте quote_decorator(say_hello) вначале сработает строка 5, произойдет вызов функции wrapper.

2. Внутри функции wrapper произойдет вызов func(), но это результат будет преобразован: добавится "обертка" в виде кавычек и собачек.

Синтаксис декораторов с @ "собачкой"

Хотя использование декоратора без @ работает, в Python существует более удобный способ применения декораторов с помощью символа @. Это позволяет сделать код более читаемым и понятным.

-3

Последовательность вызовов при этом "под капотом" останется прежней: сначала вызовется функция qoute_decorator(), которая внутри себя уже вызовет say_hello() и применит к ней "обертку".

Декораторы с параметрами

Усложним задачу. Пусть наш декоратор принимает на вход символ (или строку), которым нужно обрамлять текст функции. Например, мы хотим получить на выходе строку "?Привет!?".

-4

В классическом виде применение этого декоратора будет выглядеть вот так:

-5

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

Иногда нам нужно произвести несколько преобразований. Например, добавить обрамление с помощью quote_decorator и символов """ , а также добавить префикс перед текстом функции в виде слова Say.

-6

Когда мы вызываем say_hello(), происходит следующее:

1. Вызов quote_decorator: quote_decorator получает функцию, возвращаемую prefix_decorator, и создает новую функцию wrapper, которая будет оборачивать результат.
2. Вызов prefix_decorator: prefix_decorator получает оригинальную функцию say_hello и создает свою собственную функцию wrapper, которая добавляет префикс "Say: " к результату.
3. Вызов оригинальной функции: когда мы вызываем say_hello(), фактически вызывается wrapper из quote_decorator, который вызывает wrapper из prefix_decorator. Внутри wrapper из prefix_decorator вызывается оригинальная функция say_hello(), которая возвращает строку "Привет!".
4. Добавление префикса:prefix_decorator добавляет префикс "Say: " к результату, получая "Say: Привет!".
5. Оборачивание в кавычки:Затем quote_decorator оборачивает этот результат в указанные символы """, получая """Say: Привет!""".

Вызов классическим способом без применения @ выглядел бы вот так:

-7

Передача параметров функции в декоратор

Напишем пример с декоратором для функции add(), которая выполняет сложение двух чисел:

-8

Аргументы функции будут пробрасываться в строке 3:

  • *args означает неограниченное количество позиционных аргументов.
  • *kwargs означает неограниченное количество именованных аргументов.

Если вы не знакомы с понятием позиционных и именованных аргументов, рекомендую почитать мою статью на данную тему.

Применение декораторов

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

Вот основные сферы применения:

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

-9

2. Кэширование. Декораторы могут сохранять результаты вычислений для ускорения повторных вызовов.

-10

3. Контроля доступа (авторизация). Декораторы могут проверять права пользователя перед выполнением функции.

-11

4. Регистрации плагинов или обработчиков. Декораторы могут автоматически регистрировать функции в каком-либо списке.

-12

На этом все. Надеюсь, что эта статья помогла вам лучше понять, как работают декораторы. Пишите в комментарии, какие темы еще стоит обсудить :)

Удачи!

Другие статьи автора