我不明白以下示例,假设我有这些功能:
# 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,我认为正确的方法是没有**
而只是给出了dict。但是python显然不喜欢第二个并且告诉我我给了3而不是2个参数。
那么这背后的原因是什么?
答案 0 :(得分:124)
在第二个示例中,您提供了3个参数:filename,mode和dictionary(kwargs
)。但Python期望:2个正式参数加上关键字参数。
通过'**'为字典添加前缀,将字典kwargs
解包为关键字参数。
字典(类型dict
)是包含键值对的单个变量。
“关键字参数”是键值方法参数。
任何字典都可以通过在函数调用期间用**
作为前缀来解压缩到关键字参数。
答案 1 :(得分:9)
**
语法告诉Python将关键字参数收集到字典中。 save2
将其作为非关键字参数(字典对象)传递给它。 openX
没有看到任何关键字参数,因此**args
未被使用。它取而代之的是获得第三个非关键字参数(字典)。要解决此问题,请更改openX
函数的定义。
def openX(filename, mode, kwargs):
pass
答案 2 :(得分:1)
因为字典是单个值。如果要将其作为一组关键字参数传递,则需要使用关键字扩展。
答案 3 :(得分:1)
#2 args只是一个带有dict值的形式参数,但不是关键字类型参数。
如果要将关键字类型参数传递给关键字参数 你需要在字典之前具体**,这意味着** args
查看这个有关使用** kw
的更多细节http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
答案 4 :(得分:0)
上述内容为:
def模型(功能,目标): 全局参数 正则化器=无 regularizsation_type = args.regularizastion_type.lower ...
这是我们使用正则化方法L1和L2来最终减少过度拟合的代码的一部分。键入“ global args”后出现错误“没有名为args的模块”。
答案 5 :(得分:0)
扩展@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")
在这里您可以看到解压缩字典的工作原理,以及发送实际字典失败的原因
答案 6 :(得分:-1)
以下代码使用 kwargs
并将其转移到另一个函数:
def myprint( kwargs ):
# default values
a = kwargs.get('a', None)
b = kwargs.get('b', None)
# print both
print('a={}, b={}'.format(a,b))
def mytest( **kwargs ):
myprint( kwargs )
mytest()
mytest(b=2)
产量:
a=None, b=None
a=None, b=2