Допустим есть следующий декоратор, который сохранен в файле 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) # --------------- # Привет Андрей. # ---------------
Теперь декоратор работает так, как и ожидалось.