Декораторы - это просто функции , а функции - это просто объекты.
Линии
@make_blink
def hello_world():
# ...
по сути такие же, как
def hello_world():
# ...
hello_world = make_blink(hello_world)
за исключением того, что функциональный объект никогда не присваивается hello_world
первым (он находится в стеке для передачи декоратору).
Так что все, что вы возвращаете из make_blink()
, присваивается обратно hello_world
. Это может быть функциональный объект, но это может быть и нечто совершенно иное.
Поэтому, когда вы используете return decorator
, вы указываете Python установить hello_world
для объекта вложенной функции. Когда вы используете return decorator()
, вы указываете Python использовать результат функции decorator()
. Здесь это строковое значение. Это как если бы вы сделали это:
def hello_world():
"""Original function! """
return "Hello, World!"
hello_world = "<blink>" + hello_world() + "</blink>"
И это хорошо для этого конкретного примера, потому что тело функции hello_world()
всегда только возвращает одну и ту же строку каждый раз .
Но что, если вы изменили исходное тело функции hello_world()
, чтобы оно возвращало каждый раз что-то новое? Что если бы у вас было:
import random
@make_blink
def random_greeting():
return 'Hello ' + random.choice('DonAr', 'Martijn Pieters', 'Guido van Rossum') + '!'
Теперь имеет значение большое , что вы возвращаете из make_blink()
звонка! Для верхнего уровня модуля декораторы выполняются только один раз при импорте. Если бы вы использовали return decorator()
, вы бы запустили random.choice()
только один раз, и у вас было бы фиксированное значение random_greeting
для одного статического строкового результата.
Вообще говоря, ожидается, что декораторы снова будут возвращать вызываемый объект. Это может быть оригинальная функция (где декоратор просто обновляет какую-то регистрацию), функция-обертка (которая выполняет дополнительные действия до или после вызова оригинала) или даже что-то совершенно другое. Но это нигде не заложено в камне, и переводчику все равно.
Декораторы - это просто многократно используемые вещи для использования в вашей программе , инструмент. Если у вас есть конкретное использование для декоратора, который возвращает результат исходной функции, тогда вы можете это сделать.