На этом шаге мы рассмотрим особенности использования таких функций.
Все примеры пока что декорировали только простую нульарную функцию greet(), которая вообще не принимала никаких аргументов. Вплоть до этого момента декораторам, которые вы здесь видели, не было дела до переадресации аргументов во входную функцию.
Если применить один из этих декораторов к функции, которая принимает аргументы, то она не заработает правильно. Тогда как декорировать функцию, которая принимает произвольные аргументы?
Вот где на помощь приходят функциональные средства языка Python *args и **kwargs для работы с неизвестными количествами аргументов. Ниже приведен декоратор proxy(), в котором задействуется их преимущество:
>>> def proxy(func): def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper
С этим декоратором происходят две вещи, заслуживающие внимания:
К сожалению, в Python значение операторов "звездочка" и "двойная звездочка" перегружено и меняется в зависимости от контекста, в котором они используются, но надеемся, вы уловили идею.
Давайте расширим прием, сформулированный декоратором proxy(), в более полезный практический пример. Ниже приведен декоратор trace(), который регистрирует аргументы функции и итоговые результаты, полученные во время исполнения:
>>> def trace(func): def wrapper(*args, **kwargs): print(f'ТРАССИРОВКА: вызвана {func.__name__}() ' f'с {args}, {kwargs}') original_result = func(*args, **kwargs) print(f'ТРАССИРОВКА: {func.__name__}() ' f'вернула {original_result!r}') return original_result return wrapper
При декорировании функции с использованием декоратора trace() и последующем ее вызове, будут выведены переданные в декорированную функцию аргументы и возвращаемое ею значение. Этот пример по-прежнему остается несколько "игрушечным" - но в случае крайней необходимости он становится отличным средством отладки:
>>> @trace def say(name, line): return f'{name}: {line}' >>> say('Джейн', 'Привет, Мир') ТРАССИРОВКА: вызвана say() с ('Джейн', 'Привет, Мир'), {} ТРАССИРОВКА: say() вернула 'Джейн: Привет, Мир' 'Джейн: Привет, Мир'
Если говорить об отладке, то существует две вещи, которые при отладке декораторов следует иметь в виду.
На следующем шаге мы рассмотрим, как писать "отлаживаемые" декораторы.