Страницы

Поиск по вопросам

среда, 26 февраля 2020 г.

Как внутренняя функция декоратора получает *args и **kwargs

#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) Ну и в итоге этот аргумент у вас просто печатается на экран.

Комментариев нет:

Отправить комментарий