Передать ** kwargs аргумент другой функции с ** kwargs
Я не понимаю следующий пример, скажем, у меня есть следующие функции:
# 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
в основном является dict, поэтому, если я хочу передать аргумент openX, я думаю, что правильный путь был бы без **
и просто давал бы dict. Но python явно не нравится второй и говорит мне, что я дал 3 вместо 2 аргументов.
Так в чем причина этого?
Ответы
Ответ 1
Во втором примере вы предоставляете 3 аргумента: имя файла, режим и словарь (kwargs
). Но Python ожидает: 2 формальных аргумента плюс аргументы ключевых слов.
По префиксу словаря "**" вы распаковываете словарь kwargs
в аргументы ключевых слов.
Словарь (тип dict
) - это единственная переменная, содержащая пары ключ-значение.
"Аргументы ключевого слова" являются параметрами метода key-value.
Любой словарь может быть распакован в аргументы ключевого слова, префикс его с помощью **
во время вызова функции.
Ответ 2
Синтаксис **
указывает Python собирать аргументы ключевых слов в словаре. save2
передает его как аргумент без ключевого слова (объект словаря). openX
не видит никаких аргументов ключевого слова, поэтому **args
не используется. Вместо этого он получает третий аргумент без ключевого слова (словарь). Чтобы исправить это, измените определение функции openX
.
def openX(filename, mode, kwargs):
pass
Ответ 3
Поскольку словарь является единственным значением. Вам нужно использовать расширение ключевого слова, если вы хотите передать его как группу аргументов ключевого слова.
Ответ 4
За # 2
args будет только формальным параметром с значением dict, но не параметром типа ключевого слова.
Если вы хотите передать параметр типа ключевого слова в аргумент ключевого слова
Вам необходимо указать ** перед вашим словарем, что означает ** args
проверьте это для более подробной информации об использовании ** kw
http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
Ответ 5
Заявление к вышесказанному:
модель def (функции, цель): глобальные аргументы регуляризатор = нет регуляризатор_типа = args.regularizastion_type.lower...
Это часть кода, где мы используем подходы регуляризации L1 и L2, чтобы в конечном итоге уменьшить переоснащение. Я получаю сообщение об ошибке "нет модуля с именем args" после ввода "global args".
Ответ 6
Развернув ответ @gecco, ниже приведен пример, который покажет вам разницу:
def foo(**kwargs):
for entry in kwargs.items():
print("Key: {}, value: {}".format(entry[0], entry[1]))
# call using normal keys:
foo(a=1, b=2, c=3)
# call using an unpacked dictionary:
foo(**{"a": 1, "b":2, "c":3})
# call using a dictionary fails because the function will think you are
# giving it a positional argument
foo({"a": 1, "b": 2, "c": 3})
# this yields the same error as any other positional argument
foo(3)
foo("string")
Здесь вы можете увидеть, как работает распаковка словаря, и почему отправка реального словаря не удалась