Готовимся к собеседованию: что такое декораторы в Python
2026-02-21 07:13 Diff

#статьи

  • 1 дек 2020
  • 0

На собеседованиях только и разговоров, что о декораторах. Разбираемся на пальцах, что это.

 vlada_maestro / shutterstock

Кандидат философских наук, специалист по математическому моделированию. Пишет про Data Science, AI и программирование на Python.

Итак, вы на собеседовании на вакансию джуна-пайтониста. Всё идёт хорошо: вы объяснили про кортежи и списки, про принципы ООП и структуры данных, даже решили небольшую задачку, и вдруг:

— Расскажите, пожалуйста, про декораторы в Python.

В большинстве случаев будет достаточно сказать своими словами, что такое декоратор, и написать простейший код.

Вслух:

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

Пример кода:

Функция say_hi (пример отсюда), которую мы «обернём» в декоратор, возвращает строку «всем привет». Обратите внимание: не печатает, а возвращает.

def say_hi(): return 'всем привет'

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

Пишем декоратор:

def uppercase_decorator(function): def wrapper(): func = function() make_uppercase = func.upper() return make_uppercase return wrapper

Что здесь происходит — разбираем код построчно:

  • В первой строке мы указываем имя декоратора и то, что он принимает function в качестве своей переменной.
  • Вторая строка — это объявление функции-обёртки wrapper (). Тело обёртки в блоке состоит из трёх строк ниже. Оно как раз и описывает, что именно мы будем делать с функцией, ранее принятой декоратором.
  • Третья строка: записываем входящую переменную function () в локальную переменную func. Здесь «локальная» означает, что она действует только в рамках функции wrapper ().
  • Четвёртая строка: мы применяем к func строковый метод upper и записываем результат в другую локальную переменную make_uppercase.

Больше локальных переменных богу локальных переменных! Конечно, всё это ради понятности и читаемости.

  • Пятая строка: функция wrapper () возвращает переменную make_uppercase, то есть строку от function (), но уже прописными буквами.
  • Последняя строка: декоратор возвращает нам уже саму функцию wrapper, точнее, результат её работы над функцией function.

Как это запустить? Пишем символ @, за ним название декоратора, а объявление функции say_hi переносим на строку под ней:

@uppercase_decorator def say_hi(): return 'всем привет'

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

Получаем на выходе:

Если хочется немного дополнить, вот ещё примеры декораторов.

def logging(func): def log_function_called(): print(f'Вызвана {func}') func() return log_function_called @logging def my_name(): print('Крис') @logging def friends_name(): print('Наруто') my_name() friends_name()Источник

Что здесь происходит:

Декоратор принимает в качестве переменной функцию func. Затем функция-обёртка log_function_called печатает «Вызвана func» и запускает её на выполнение. Функции my_name и friends_name печатают имена Крис и Наруто, а в обёрнутом виде декоратор предваряет их выполнение сообщением об их вызове.

def benchmark(func): import time def wrapper(): start = time.time() func() end = time.time() print('[*] Время выполнения: {} секунд.'.format(end - start)) return wrapper @benchmark def fetch_webpage(): import requests webpage = requests.get('https://skillbox.ru') print(webpage) fetch_webpage()Источник

Что здесь происходит:

В объявлении декоратора benchmark мы импортируем библиотеку time. В функции-обёртке wrapper засекаем время в переменную start, затем выполняем полученную декоратором функцию, а после этого фиксируем время в переменную end. Далее печатаем время выполнения, просто отняв от величины end величину start прямо внутри команды print.

Сама функция fetch_webpage делает простой GET-запрос на наш сайт. Для этого она импортирует популярную библиотеку requests, записывает в переменную webpage ответ сервера Skillbox на запрос и печатает эту переменную.

В обёрнутом виде декоратор «запускает секундомер», функция fetch_webpage делает запрос и печатает ответ, после чего декоратор «выключает секундомер» и печатает время, которое функция потратила на всю эту работу.

Если хотите произвести впечатление, то можно добавить, что:

  • Декоратор — это паттерн проектирования (design pattern) в Python, а также функция второго уровня, то есть принимающая другие функции в качестве переменных и возвращающая их.
  • И в сам декоратор, и в функцию-обёртку можно передать и позиционные, и именованные аргументы — args и kwargs соответственно.
  • Декораторы работают не только с функциями, но и с классами и методами.

Конечно, на собеседовании надо будет пояснить все эти пункты и проиллюстрировать их кодом. На курсе Профессия Python-разработчик вы изучите не только декораторы, но и всё необходимое для того, чтобы с блеском проходить любые собеседования.

Бесплатный курс по Python ➞
Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу