Рубрики
Без рубрики

Понимание Python * Args и ** Kwargs

Python * args и ** Kwargs – это супер полезные инструменты, что при правильном использовании может сделать ваш код … Помечено CodeNewie, начинающим, Python.

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”