Перейти к содержанию

Начало урока

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

Оберните функцию дополнительным поведением, не трогая её код

Главная идея: декоратор — это функция, которая принимает другую функцию, оборачивает её дополнительным поведением и возвращает обёрнутый вариант. Строка @decorator — просто удобное сокращение для переприсваивания функции её обёрнутой версии. Так можно добавить логирование, замер времени, кэширование или проверку доступа сразу многим функциям, не редактируя ни одну из них.
К концу вы сможете:
  • объяснить, почему функции — это объекты первого класса,
  • написать вложенную функцию-обёртку, которая замыкается над другой функцией,
  • создать декоратор и применить его через @,
  • передавать любые аргументы через *args, **kwargs,
  • сохранять исходное имя и строку документации с помощью functools.wraps.

1. Функции — объекты первого класса

Прежде чем декораторы обретут смысл, запомните один факт: в Python функция — это обычный объект, как число или список. Её можно сохранить в переменной, положить в список, передать в другую функцию как аргумент и даже вернуть из функции.

def shout(text):
    return text.upper()

yell = shout           # store the function object (no parentheses!)
print(yell("hello"))   # HELLO

def run_twice(func, value):
    return func(value) + " " + func(value)

print(run_twice(shout, "hi"))   # HI HI

Обратите внимание: в yell = shout нет скобок — мы копируем саму функцию, а не её результат. Именно на этой возможности передавать функции и строится декоратор.

2. Вложенные функции и замыкания

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

def make_multiplier(factor):
    def multiply(n):
        return n * factor      # 'factor' comes from the outer scope
    return multiply            # return the inner function object

triple = make_multiplier(3)
print(triple(10))   # 30
print(triple(4))    # 12

make_multiplier возвращает внутреннюю функцию multiply, которая по-прежнему помнит factor = 3. Декоратор устроен точно так же: внешняя функция определяет и возвращает внутреннюю обёртку.

Продолжите этот урок на YourAIZone

В полном уроке — объяснение целиком, разобранные примеры, частые ошибки, тесты с мгновенной проверкой и ИИ-репетитор. Начните сразу как гость или создайте аккаунт, чтобы сохранять прогресс.

В полном уроке

  • Объяснение целиком
  • Разобранные примеры
  • Частые ошибки и как их избежать
  • Тестовые вопросы: 15
  • ИИ-репетитор, который отвечает на вопросы по теме
  • Отслеживание прогресса для ученика, родителей и учителя