#python #python_3x
Вот для примера функция с декоратором from datetime import datetime def add_log_info(func): def wrapper(*args, **kwargs): print(f'{datetime.now()}: Вызвана функция {func.__name__}') result = func(*args, **kwargs) return result return wrapper @add_log_info def say_my_name(name): print(f'Your name in {name}') say_my_name('Вася') Я не могу понять как функция wrapper получает аргументы *args и **kwargs. В момент когда функция say_my_name передается в декоратор, она ведь еще не вызвана, насколько я понимаю мы как бы передаем саму функцию туда, само ее определение. Но тогда как вместе с ней передаются аргументы, которые в итоге передаются транзитом в вызов func из wrapper? Надеюсь, что мой вопрос понятен :)
Ответы
Ответ 1
Если говорить в терминах вашего примера, то после декорирования имя say_my_name обозначает уже не саму эту функцию, а wrapper. А сама эта функция теперь лежит внутри wrapper под именем func. То есть когда вы делаете вызов этой функции, происходит следующее: Вы вызываете say_my_name('Вася') Так как теперь под этим именем уже не сама функция, а обертка вокруг неё, то происходит вызов этой обёртки (wrapper), а аргументы (в данном случае один аргумент Вася) передаются во wrapper. Так как wrapper принимает *args, **kwargs, то у вас args становится списком ['Вася'], а на kwargs уже никаких аргументов не осталось, это просто пустой словарь. Внутри обёртки у вас дёргается функция func, которая является просто псевдонимом для того, что было первоначальной функцией say_my_name, но потеряло право так называться после декорирования. В эту func передаются аргументы *['Вася'], **{} - то есть просто один позиционный аргумент 'Вася'. А у нас func как раз и принимает один аргумент name. (Так как func - это же бывшая say_my_name) Ну и в итоге этот аргумент у вас просто печатается на экран.
Комментариев нет:
Отправить комментарий