Передача Параметров в Декоратор Python • Что такое kwargs

Инструменты-помощники системного администратора: 💫 💫 💫 💫 💫 читайте на сайте

В предыдущем примере функция currency() — декоратор. С ее помощью вы можете декорировать функцию net_price следующим образом: Чтобы использовать декоратор currency , нужно передать функцию net_price , чтобы получить новую функцию и выполнть ее, как если бы это была исходная функция. Декоратор Decorator структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту.

Как создать декоратор Python, который можно использовать с параметрами или без них?

Я хотел бы создать декоратор Python, который можно использовать либо с параметрами:

или без них (например, чтобы перенаправить вывод на stderr по умолчанию):

Обратите внимание, что я не ищу другого решения проблемы перенаправления вывода, это просто пример синтаксиса, которого я хотел бы добиться.

Выглядящий по умолчанию @redirect_output удивительно неинформативно. Я бы сказал, что это плохая идея. Используйте первую форму и значительно упростите себе жизнь. — S.Lott

хотя интересный вопрос — пока я не увидел его и не просмотрел документацию, я бы предположил, что @f был таким же, как @f(), и я все еще думаю, что это должно быть, если честно (любые предоставленные аргументы будут просто добавлены к аргументу функции) — rog

Передача Параметров в Декоратор Python • Что такое kwargs

Чоповец Владимир Петрович, специалист по ремонту ноутбуков
Мнение эксперта
Чоповец Владимир Петрович, специалист по ремонту ноутбуков
Если у вас не получается разобраться самостоятельно, пишите мне, я помогу!
Задать вопрос эксперту
Использование аргументов ключевого слова со значениями по умолчанию как предложено kquinn хорошая идея, но вам потребуется включить скобки. Если самостоятельно разобраться в нюансах не получается, пишите мне!

Python: *args, **kwargs и декораторы для начинающих

13 ответы

Я знаю, что этот вопрос старый, но некоторые комментарии новые, и хотя все жизнеспособные решения по существу одинаковы, большинство из них не очень понятны или легко читаются.

Как говорится в ответе, единственный способ справиться с обоими случаями — проверить оба сценария. Самый простой способ — просто проверить, есть ли единственный аргумент, и это callabe (ПРИМЕЧАНИЕ: потребуются дополнительные проверки, если ваш декоратор принимает только 1 аргумент и он является вызываемым объектом):

В первом случае вы делаете то, что делает любой обычный декоратор, возвращаете модифицированную или обернутую версию переданной функции.

Во втором случае вы возвращаете «новый» декоратор, который каким-то образом использует информацию, переданную с помощью *args, **kwargs.

Это хорошо и все такое, но необходимость писать это для каждого декоратора, который вы делаете, может быть довольно раздражающей и не такой чистой. Вместо этого было бы неплохо иметь возможность автоматически изменять наши декораторы, не переписывая их. но для этого и нужны декораторы!

Используя следующий декоратор-декоратор, мы можем удалить наши декораторы, чтобы их можно было использовать с аргументами или без них:

Теперь мы можем украсить наши декораторы @doublewrap, и они будут работать как с аргументами, так и без них, с одной оговоркой:

Я отметил выше, но должен повторить здесь, проверка в этом декораторе делает предположение об аргументах, которые декоратор может получить (а именно, что он не может получить ни одного вызываемого аргумента). Поскольку сейчас мы делаем его применимым к любому генератору, его нужно иметь в виду или модифицировать, если он будет противоречить.

Использование аргументов ключевого слова со значениями по умолчанию (как предложено kquinn) — хорошая идея, но вам потребуется включить скобки:

Если вам нужна версия, которая работает без круглых скобок в декораторе, вам придется учитывать оба сценария в коде декоратора.

Если вы использовали Python 3.0, вы могли бы использовать для этого только аргументы ключевого слова:

В Python 2.x это можно эмулировать с помощью трюков с varargs:

Любая из этих версий позволит вам написать такой код:

Что ты вставляешь your code here ? Как вы называете украшенную функцию? fn(*args, **kwargs) не работает. — люм

То, как они это делают, довольно просто. Они добавляют kwarg ( function=None ) перед их аргументами декоратора. Если декоратор используется один, function будет фактической функцией, которую она украшает, тогда как если она вызывается с аргументами, function будет None .

Я считаю этот подход, который использует django, более элегантным и простым для понимания, чем любой из других методов, предложенных здесь.

Да, мне нравится этот метод. Обратите внимание, что вы иметь использовать kwargs при вызове декоратора, в противном случае первый позиционный аргумент назначается function а затем все ломается, потому что декоратор пытается вызвать этот первый позиционный аргумент, как если бы это была ваша декорированная функция. — Дастин Вятт

Передача Параметров в Декоратор Python • Что такое kwargs

Декоратор (Decorator) — структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту. Шаблон Декоратор предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности. 1

Это должно быть нормально, если вы не хотите использовать функцию в качестве аргумента для вашего декоратора, и в этом случае декоратор ошибочно предположит, что у него нет аргументов. Я отметил выше, но должен повторить здесь, проверка в этом декораторе делает предположение об аргументах, которые декоратор может получить а именно, что он не может получить ни одного вызываемого аргумента.

def infunc():
print(‘

‘)
func()
print(‘

‘)
return infunc

Теперь в переменной somef окажется значение функции infunc. Таким образом мы задекорировали нашу функцию. И в Python подобная конструкция заменяется знаком @ и именем декоратора:

Таким образом можно придать дополнительную функциональность любому объекту. Если же мы захотим превратить текст в таблицу и оформить его соответствующим образом, просто создадим еще один декоратор по примеру выше заменив тег h1 на table:

# навешиваем декоратор с тегом table поверх h1
@decorator2
@decorator
def somef():
print(«Some Func»)

Вызов функции часто сопровождается передачей в нее аргументов.

# но вызов функции далее преведет к ошибке так как infunc не принимает аргументы
somef(«XX»)

# чтобы исправить это дополним декоратор
def decorator2(func):

Так как функция somef(name, age) может содержать заранее неизвестное количество аргументов , то вышеуказанный способ описания позволяет декорировать функции с произвольным количеством аргументов.

Таким образом мы рассмотрели способ расширения функциональности объекта в Python, с помощью декоратора.

Передача Параметров в Декоратор Python • Что такое kwargs

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Декораторы в Python
без причудливых обходных путей, я нахожу это странным, и мне нравится иметь возможность просто украсить @decorator .
Чоповец Владимир Петрович, специалист по ремонту ноутбуков
Мнение эксперта
Чоповец Владимир Петрович, специалист по ремонту ноутбуков
Если у вас не получается разобраться самостоятельно, пишите мне, я помогу!
Задать вопрос эксперту
Замыкание, говоря коротко, представляет собой передачу в качестве аргумента одной функции, другую, обработку ее во вложенной функции и возвращение вложенной функции. Если самостоятельно разобраться в нюансах не получается, пишите мне!

StackOverGo — Как создать декоратор Python, который можно использовать как с параметрами, так и без них?

Понравилось? Поделись с друзьями:
Оставить отзыв

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

Контакты · Политика конфиденциальности · О проекте · Популярные разделы по сайта · Реклама · Согласие на обработку персональных данных · Пользовательское соглашение