Сообщить об ошибке.

Возврат значений из декорируемой функции

Допустим есть следующий декоратор, который сохранен в файле decorator.py:

def talk(func):
    def wrapper(*args, **kwargs):
        dash = '-'*15
        print(dash)
        func(*args, **kwargs)
        print(dash)
    return wrapper

И мы хотим декорировать простую функцию, которая возвращает значение:

from decorator import talk

@talk
def say(name):
    return f'Привет {name}.'

# вызов декорируемой функции
>>> string = say('Андрей')
# ---------------
# ---------------
>>> print(string)
# None

Декоратор съел возвращаемое значение из функции say(), так как вложенная функция wrapper() явно НЕ возвращает какого либо значения и в итоге вызов декорируемой функции say('Андрей'), в примере выше, вернул значение None.

Чтобы исправить этот недочет, необходимо сделать так, чтобы функция-обертка возвращала задекорированное значение, которое в свою очередь возвращает функция. Изменим декоратор talk, который сохранен в файле decorator.py следующим образом:

def talk(func):
    def wrapper(*args, **kwargs):
        dash = '-'*15
        string = func(*args, **kwargs)
        return dash + '\n' + string + '\n' + dash
    return wrapper

Мы знаем, что операторы и функций определенные в модуле инициализируются в момент импорта модуля и выполняются только один раз, следовательно, что бы изменения, сделанные в файле модуля декоратора decorator.py вступили в силу, нужно выйти и снова зайти в интерактивный режим и произвести все операции заново.

Следовательно теперь нужно выйти из интерактивного режима интерпретатора Python и снова зайти, затем снова выполнить импорт декоратора talk и применить его к функции say():

from decorator import talk

@talk
def say(name):
    return f'Привет {name}.'

>>> string = say('Андрей')
>>> print(string)
# ---------------
# Привет Андрей.
# ---------------

Теперь декоратор работает так, как и ожидалось.