What is the purpose and use of **kwargs? [duplicate]
Какова цель и использование ** kwargs?
Для чего используется **kwargs в Python?
Я знаю, что вы можете выполнить objects.filter над таблицей и передать в **kwargs аргумент.
Могу ли я также сделать это для указания временных интервалов, т.е.timedelta(hours = time1)?
Как именно это работает? Классифицируется ли это как "распаковка"? Нравится a,b=1,2?
Переведено автоматически
Ответ 1
Вы можете использовать **kwargs, чтобы позволить вашим функциям принимать произвольное количество аргументов ключевого слова ("kwargs" означает "аргументы ключевого слова"):
>>> defprint_keyword_args(**kwargs): ... # kwargs is a dict of the keyword args passed to the function ... for key, value in kwargs.iteritems(): ... print"%s = %s" % (key, value) ... >>> print_keyword_args(first_name="John", last_name="Doe") first_name = John last_name = Doe
Вы также можете использовать **kwargs синтаксис при вызове функций, создав словарь аргументов ключевого слова и передав его вашей функции:
>>> kwargs = {'first_name': 'Bobby', 'last_name': 'Smith'} >>> print_keyword_args(**kwargs) first_name = Bobby last_name = Smith
В руководстве по Python содержится хорошее объяснение того, как это работает, наряду с несколькими приятными примерами.
Обновление для Python 3
Для Python 3 вместо iteritems() используйте items()
Ответ 2
Распаковка словарей
** распаковывает словари.
Это
func(a=1, b=2, c=3)
это то же самое, что
args = {'a': 1, 'b': 2, 'c':3} func(**args)
Это полезно, если вам нужно создать параметры:
args = {'name': person.name} ifhasattr(person, "address"): args["address"] = person.address func(**args) # either expanded to func(name=person.name) or # func(name=person.name, address=person.address)
Упаковка параметров функции
Использовать .items() вместо .iteritems() для python 3
defsetstyle(**styles): for key, value in styles.iteritems(): # styles is a regular dictionary setattr(someobject, key, value)
Это позволяет вам использовать функцию следующим образом:
setstyle(color="red", bold=False)
Примечания
kwargs если имя переменной используется для аргументов ключевого слова, можно использовать другое имя переменной. Важной частью является то, что это словарь, и он распаковывается с помощью оператора двойной звездочки **.
Другие итеративные файлы распаковываются с помощью единственного оператора asterisk *
Чтобы избежать путаницы, вероятно, лучше придерживаться распознанных имен переменных, kwargs и args для словарей и других итеративных объектов соответственно.
kwargs - это просто словарь, который добавляется к параметрам.
Словарь может содержать пары ключ-значение. И это kwargs . Хорошо, вот как.
Вопрос "Зачем" не так прост.
Например (очень гипотетически) у вас есть интерфейс, который просто вызывает другие подпрограммы для выполнения задания:
defmyDo(what, where, why): if what == 'swim': doSwim(where, why) elif what == 'walk': doWalk(where, why) ...
Теперь вы получаете новый метод "drive":
elif what == 'drive': doDrive(where, why, vehicle)
Но подождите минутку, появился новый параметр "vehicle" - вы не знали его раньше. Теперь вы должны добавить его в сигнатуру myDo-функции.
Здесь вы можете использовать kwargs - вы просто добавляете kwargs в подпись:
defmyDo(what, where, why, **kwargs): if what == 'drive': doDrive(where, why, **kwargs) elif what == 'swim': doSwim(where, why, **kwargs)
Таким образом, вам не нужно изменять сигнатуру вашей интерфейсной функции каждый раз, когда могут измениться некоторые из вызываемых вами подпрограмм.
Это всего лишь один хороший пример, который может оказаться полезным для kwargs.
Ответ 4
Исходя из того, что хороший пример иногда лучше длинного рассуждения, я напишу две функции, используя все средства передачи аргументов переменных python (как позиционные, так и именованные аргументы). Вы должны легко увидеть, что это делает, самостоятельно.:
deff(a = 0, *args, **kwargs): print("Received by f(a, *args, **kwargs)") print("=> f(a=%s, args=%s, kwargs=%s" % (a, args, kwargs)) print("Calling g(10, 11, 12, *args, d = 13, e = 14, **kwargs)") g(10, 11, 12, *args, d = 13, e = 14, **kwargs)
defg(f, g = 0, *args, **kwargs): print("Received by g(f, g = 0, *args, **kwargs)") print("=> g(f=%s, g=%s, args=%s, kwargs=%s)" % (f, g, args, kwargs))
print("Calling f(1, 2, 3, 4, b = 5, c = 6)") f(1, 2, 3, 4, b = 5, c = 6)
И вот результат:
Calling f(1, 2, 3, 4, b = 5, c = 6) Received by f(a, *args, **kwargs) => f(a=1, args=(2, 3, 4), kwargs={'c': 6, 'b': 5} Calling g(10, 11, 12, *args, d = 13, e = 14, **kwargs) Received by g(f, g = 0, *args, **kwargs) => g(f=10, g=11, args=(12, 2, 3, 4), kwargs={'c': 6, 'b': 5, 'e': 14, 'd': 13})