Я не понимаю следующий пример, допустим, у меня есть эти функции:
# python likes
def save(filename, data, **kwargs):
fo = openX(filename, "w", **kwargs) # <- #1
fo.write(data)
fo.close()
# python doesnt like
def save2(filename, data, **kwargs):
fo = openX(filename, "w", kwargs) # <- #2
fo.write(data)
fo.close()
def openX(filename, mode, **kwargs):
#doing something fancy and returning a file object
Почему № 1 - правильное решение, а № 2 - неправильное? **kwargs
это в основном диктат, поэтому, если я хочу передать аргумент openX, я думаю, что правильный путь был бы без **
и просто дать диктат. Но python явно не нравится второй и говорит мне, что я дал 3 вместо 2 аргументов. Так в чем же причина?
**args
в коде? Возможно, это худшее из возможных имен, так как люди будут путать его с*args
Ответы:
Во втором примере вы предоставляете 3 аргумента: имя файла, режим и словарь (
kwargs
). Но Python ожидает: 2 формальных аргумента плюс аргументы с ключевыми словами.Префикс словаря с помощью «**» позволяет распаковать словарь
kwargs
в аргументы ключевых слов.Словарь (тип
dict
) - это отдельная переменная, содержащая пары ключ-значение.«Аргументы ключевого слова» являются методами-ключами-значениями-параметрами.
Любой словарь можно распаковать в аргументы ключевого слова, поставив перед ним префикс
**
во время вызова функции.источник
**
Синтаксис говорит Python для сбора ключевых слов аргументов в словарь. Онsave2
передает его как аргумент без ключевого слова (объект словаря). TheopenX
не видит никаких аргументов ключевого слова, поэтому**args
не привыкает. Вместо этого он получает третий аргумент без ключевого слова (словарь). Чтобы исправить это, измените определениеopenX
функции.источник
Развернув ответ @gecco, ниже приведен пример, который покажет разницу:
Здесь вы можете увидеть, как работает распаковка словаря, и почему отправка реального словаря не удалась
источник
Потому что словарь - это одно значение. Вам нужно использовать расширение ключевых слов, если вы хотите передать его как группу аргументов ключевых слов.
источник
Для # 2 аргументы будут только формальным параметром со значением dict, но не параметром типа ключевого слова.
Если вы хотите передать параметр типа ключевого слова в аргумент ключевого слова, вам нужно указать ** перед вашим словарем, что означает ** args
проверить это для более подробной информации об использовании ** кВт
http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
источник