Я немного разбираюсь в декораторах из большого учебника по thecodeship, но нашел себя в некоторой степени путаным с помощью одного примера.Пример декоратора Python
Сначала приведен простой пример, за которым следует объяснение, для какого декоратора.
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
my_get_text = p_decorate(get_text)
print my_get_text("John")
Теперь это имеет смысл для меня. Декоратор - это просто обертка для функции. И в объяснении этих парней он говорит, что декоратор - это функция, которая принимает другую функцию в качестве аргумента, генерирует новую функцию и возвращает сгенерированную функцию, которая будет использоваться где угодно.
А теперь эквивалентно выше код:
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
@p_decorate
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
print get_text("John")
Я считаю, что я понимаю, как декоратор инициализируется, когда не дали никаких аргументов. Поправьте меня, если я ошибаюсь.
- декоратор по умолчанию переходит в функции
get_text
и потому, чтоp_decorate
возвращает функциюfunc_wrapper
, мы в конечном итоге с истинным утверждениемget_text = func_wrapper
.
Что для меня важно, это первый эквивалент кода, потому что я вижу и понимаю, как работает декоратор.
Что очень меня смущает следующий код:
def tags(tag_name):
def tags_decorator(func):
def func_wrapper(name):
return "<{0}>{1}</{0}>".format(tag_name, func(name))
return func_wrapper
return tags_decorator
@tags("p")
def get_text(name):
return "Hello "+name
print get_text("John")
Опять же, поправьте меня, если я ошибаюсь, но это мое понимание.
- Декоратор принимает строку тега «p» вместо имени функции по умолчанию . И, в свою очередь, функция
tags_decorator
предполагает, что параметр, который будет передан, является функцией , украшаемой,get_text
.
Возможно, было бы полезно увидеть эквивалентный блок кода в форме «не-декоратор», но я не могу оглянуться, как это будет выглядеть. Я также не понимаю, почему возвращаются tags_decorator
и func_wrapper
. Какова цель возвращения двух разных функций, если декоратору нужно только вернуть 1 функцию для обертывания get_text
.
Как примечание стороны, это действительно сводится к следующему.
- Может ли этот блок быть упрощен чем-то меньшим, чем набор из 3 функций?
- Может ли декораторы принять более 1 аргумент для упрощения кода?
спасибо. И я сделал короткое редактирование после вашего ответа. Почему именно эти функции возвращают 2 функции, а не 1? – Max
@Max: см. Мое последнее редактирование. Один из них - декоратор (изготовитель фабрики декораторов), другой - обертка, заменяющая оригинальную функцию, результат декоратора. –
Теперь я понимаю, что цель 2 вызова функций. Я могу сделать специальный декоратор с фабрикой декоратора, чтобы дополнительно указать мою последнюю обертку. – Max