Python * args
и ** kwargs
являются супер полезными инструментами, которые при правильном использовании могут заставить вас код намного проще и легче поддерживать. Большие ручные преобразования из набора данных на функциональные аргументы могут быть упакованы и распакованы в списки или словари. Остерегайтесь, хотя эта сила может привести к некоторому действительно нечитаемому/непригодным коде, если сделано неправильно.
* args предназначены для списков
* ARGS – это какой-то волшебный синтаксис, который будет собирать аргументы функций в список или распаковать список в отдельных аргументах.
При получении переменных как *
, обычно * args
аргументы получают Упаковано в упорядоченный список.
Никогда не добавляйте * args на определение вашей функции (почти никогда)
Вообще я нахожу * args
Плохое название и он только заставляет путаницу пользователю, глядя на вашу функцию, пытаясь решить, что именно это делает. Здесь я выбрал имя printrows.
Так как мы печатаем каждый предмет как строка.
def printer(*printrows: str) -> None: for i, row in enumerate(printrows): print(i, row)
>>> printer('eggs', 'spam', 'ham') 0 eggs 1 spam 2 ham
Будьте в курсе Antipatterns
Если ваш * args
Коллекция – это выделенно разные вещи, затем делают их отдельные переменные. Использование * args
Как костыль может привести к действительно запутанному API для ваших пользователей, даже самого себя.
❌
Здесь * args
сбивает с толку, как мы немного не уверены, что перейти к get_user_data
или какой заказ ему необходимо, не прочитав код.
def get_user_data(*args): "does stuff given a users GitHub and DevTo username" github = reuqests.get(f'https://api.github.com/users/{args[0]}') devto = requests.get(f'https://dev.to/api/users/by_username?url={args[1]}') ...
✔
Здесь функция подпись делает его понятно, что get_user_data
ожидает. Пользователям не придется читать вашу DOCSTRING или ухудшить ваш исходный код, чтобы понять его каждый раз, когда его ссылка на него.
def get_user_data(github_username, devto_username): "does stuff given a users GitHub and DevTo username" github = reuqests.get(f'https://api.github.com/users/{github_username}') devto = requests.get(f'https://dev.to/api/users/by_username?url={devto_username}') ...
Обратно мы можем отправить список вещей как отдельные аргументы по распаковывать их в звонок функции.
>>> things_to_print = ['eggs', 'spam', 'ham'] >>> printer(*things_to_print) 0 eggs 1 spam 2 ham
** Kwargs для словарей
Так же, как * args
Быть для списков, ** kwargs
на словарях. При упаковке их внутри функции. Имя аргумента прошло, становится ключом, то принры происходят при распаковке, ключ становится аргументом для функции.
Вот функция, принимающая ** printrows.
как это только вход. Любой ключевой аргумент, который вы проходите в функцию, будут упакованы в словарь.
def printer(**printrows: str) -> None: for key in printrows: print(key, printrows[key])
>>> printer(breakfast='eggs', lunch='spam', dinner='ham') breakfast eggs lunch spam dinner ham
Любые аргументы прошли, будут бросать Типеррр
С момента этого Принтер
не принимает никаких позиционных аргументов.
>>>printer('one') -------------------------------------------------------------------------------- TypeError Traceback (most recent call last)in ---------> 1 printer("one") TypeError: printer() takes 0 positional arguments but 1 was given
Избегать антиблокировки
Как и выше, если ваши вещи явно отделяют вещи, сделайте их отдельными вещами и не используйте ** kwargs.
. ** kwargs
Отлично подходят, когда у вас есть коллекции вещей, которые все обрабатывают именно Сэм, если они получают обрабатываемую по-другому, или вы ожидаете, что определенные ключи всегда существуют, это будет очень запутанному своим пользователям, что им нужно пройти.
Отправка ** kwargs
довольно полезно. Особенно при сочетании различных библиотек вместе. Часто вы можете сбрать объекты в словарь, часто с чем-то вроде .to_dict. ()
Затем пропустите этот все словарь к другой функции. Это делает склеивать разные библиотеки вместе ветер.
>>> things_to_print = {breakfast:'eggs', lunch:'spam', dinner:'ham'} >>> printer(**things_to_print) breakfast eggs lunch spam dinner ham
Я настроил reft.it с этими примерами, чтобы вы могли быстро прыгать, запустить его, сломать его, исправить его, добавить точки останова и действительно чувствую себя самим. Проверьте это 👉
Я надеюсь, что это поможет вам понять * args
и ** kwargs
чуть больше. Они могут быть довольно удобны для значительного упрощения повторяющегося кода, особенно если у нас уже есть настройка данных в правой структуре данных.
👀 Смотрите проблему, отредактируйте этот пост на Гадость
Оригинал: “https://dev.to/waylonwalker/understanding-python-args-and-kwargs-46bg”