2013-09-27 2 views
-1

У меня есть код:Сохраняет ли декоратор более одного возвращаемого значения?

def my_decorator(target): 
    def wrapper(): 
     print('Calling function "%s"' % target.__name__) 
     return target() # 1 
    return wrapper # 2 
@my_decorator 
def my_target(): # 3 
    print('Hi. I am the target.') 
my_target() 

я опишу то, что я понимаю, об этом шаблон Disorderly.

# 3 Мы передаем функцию my_target в качестве аргумента декоратору my_decorator. Нет проблем.

# 1 На самом деле мы вызываем функцию my_target.

# 2 (мои сомнения). Когда мы вызываем функцию в # 1, она будет печатать и возвращаться к wrapper'Hi. I am the target.', поэтому wrapper теперь сохраняет печать с my_target. Затем в # 2 вызывается ссылка от wrapper(). Поэтому после этого вызова, wrapper ссылка запустит print('..'), установленную в себе функцию и вернет значение, хранящееся ранее в нем («Привет. Я - цель», как упоминалось в начале). Итак, функция wrapperstores два значения?

+0

моя голова только начала болеть, читая мысли ... –

+0

'' wrapper'' * - нормальная функция, в # 2 вы ее не называете, вы просто возвращаете ее. И что вы подразумеваете под «функцией сохранения значений»? – fjarri

+0

Я имею в виду, что когда у меня есть функция и я возвращаю что-то, функция получает возвращаемое значение и сохраняет его в каком-то подземном мире (например, строка «привет» или bool True), чтобы использовать в другой части моего кода. Редактировать: Я неправильно понял это так? – ovrwngtvity

ответ

4

Обертка хранит функцию для вызова. Он печатает, а затем вызывает функцию и возвращает возвращаемое значение функции. Независимо от того, что делает эта функция, это не его бизнес.

3

Он может помочь вам распаковать ваш пример без использования синтаксиса @decorator. Прежде всего, давайте поймем, что делает @decorator. Объявление:

@decorator 
def func(): 
    pass 

эквивалентно:

def func(): 
    pass 
func = decorator(func) 

Чтобы сделать вещи легче понять, я предлагаю делать это вручную, но выбор другое имя для украшенной версии вашей функции:

def decorator(target): 
    print("In the decorator") 
    def wrapper(): 
     print("In the wrapper") 
     target() 
    return wrapper 

def my_target(): 
    print("In the target") 

my_decorated_target = decorator(my_target) # this will print "In the decorator" 

my_decorated_target() # prints "In the wrapper" then "In the target" 

Обратите внимание, что «В декораторе» печатается, когда декоратор применяется к целевой функции, а не когда декорированная функция вызывается позже. Вы также можете по-прежнему вызывать оригинальную функцию my_target, если хотите, поскольку она по-прежнему доступна.

Смежные вопросы