Добрый день! Сегодня речь пойдет о декораторах. Как-то давно, когда я изучал Python и старался применять его на практике, наткнулся на такой странный для меня и совсем уж не понятный синтаксис вида @decorator. Пытался я, значит, найти в интернете, что же это такое, и вот тогда еле-еле разобрался. А вы знаете, что это за "зверь"-то такой, да еще и с собачкой? Давайте разбираться!
Для начала, дадим определение тому, что является декоратором в Python, согласно документации Python:
Декоратор - это имя, используемое для шаблона проектирования программного обеспечения. Декораторы динамически изменяют функциональность функции, метода или класса без необходимости напрямую использовать подклассы или изменять исходный код декорируемой функции.
Думаю, что в целом всё понятно. В общем, это штуковина с особым синтаксисом, которая динамически может поменять что-либо в функциональности функции или класса, при этом она это может делать без изменения кода исходного кода. Звучит не плохо, да?
Синтаксис
Данный синтаксис был реализован в Python 2.4a2:
@dec2
@dec1
def func(arg1, arg2, ...):
pass
И является эквивалентным этому:
def func(arg1, arg2, ...):
pass
func = dec2(dec1(func))
То есть, в данном случае, это всего лишь одна функция, принимающая другую функцию в качестве аргумента, которая принимает декорируемую функцию.
Пример
Разберем это на примере функции, которая возвращает переданную в нее какую-нибудь фразу, а декоратор обработает и вернет её в верхнем регистре.
Напишем функцию, возвращающую какую-нибудь фразу:
def say_something(phrase):
return phrase
Напишем функцию-декоратор:
def uppercase_decorator(func):
def wrapper(*args, **kwargs):
f = func(*args, **kwargs)
upper = f.upper()
return upper
return wrapper
Эта функция принимает декорируемую функцию и возвращает функцию-обертку, в которой исполняется say_something() результат её исполнения присваивается переменной f, затем содержимое f приводится к верхнему регистру и присваивается переменной upper, затем upper возвращается.
Соберем всё это вместе:
Если было полезным, ставьте лайки, оставляйте комментарии, задавайте вопросы, если что-то было непонятно или не ясно.
Спасибо за внимание!