Функции-декораторы
Декоратор – приём программирования, который позволяет взять существующую функцию и изменить/расширить её поведение.
Декоратор получает функцию и возвращает обёртку, которая делает что-то своё «вокруг» вызова основной функции.
Простенький пример
Давайте самый простой пример декоратора, который пишет в вывод программы о том, что функция с каким-то именем была вызвана.
Если посмотреть определение выше, то вы заметите, что наш декоратор соответствует описанному.
Функция log
получает оригинальную функцию и возвращает функцию-обертку(фейковую), которая в свою очередь вызывает оригинальную и реализовывает дополнительный функционал(в нашем случае вывод сообщения в лог)
note
Обратите внимание на то, что мы получаем оригинальное имя функции через обращение к аттрибуту __name__
объекта функции.
Как применять декоратор к функции
Без специального синтаксиса
Отлично, мы написали функцию-декоратор, но что с ним делать дальше? Давайте начнем с простого примера.
note
Должен напомнить, что функции в языке Python являются объектами первого класса - это значит, что:
- функцию можно передать как аргумент при вызове другой фунции
- можно вернуть объект функции как результат работы функции
Представим, что у нас нет специального синтаксиса декораторов, то как можно применить декорирующую функцию к другой функции?
Ну примерно так👆. Как видно, мы определили оригинальную функцию, вызвали декоратор log
и переопределили значение переменной original.
Теперь, при вызове функции original
мы будем видеть следующее сообщение в терминале:
@
С использованием символа Пример выше вполне себе рабочий, но чтобы сделать применение декораторов удобнее, мы можем воспользоваться специальным синтаксисом:
Так то удобнее!
Конфигурируемые декораторы
В дальнейшем вы может встретите, декораторы которые можно конфигурировать, но как это работает? В действительности вы можете написать функцию, которая в свою очередь будет возвращать функцию-декоратор. Примерно так:
Применение декораторов к классам и методам классов
Применять декораторы можно не только к функциям, а так же к классам и методам классов.
TODO: Дописать примеры