如果存在同名的位置参数,为什么kwargs中的键被丢弃?

时间:2014-05-20 21:59:29

标签: python kwargs

我刚遇到这种让我感到惊讶的行为:

def my_func(a=4, **kwargs):
    print kwargs

演示:

>>> my_func(a=5, b=6)
{'b': 6}  # I was expecting {'a' : 4, 'b' : 6}
          # Maybe {'a' : 5, 'b' : 6}

另外,如果我得到,我不会感到惊讶:

SyntaxError: keyword argument repeated

,如

>>> my_func(a=4, a=5)
  File "<stdin>", line 1
SyntaxError: keyword argument repeated

TypeError: my_func() got multiple values for keyword argument 'a'

,如

>>> my_func(a=4, **{'a' : 5, 'b' : 6})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: my_func() got multiple values for keyword argument 'a'

python遵循什么规则来删除关键字'a'?

也许我错过了一些明显的或关键的术语,但我无法通过搜索找到解决方案。

2 个答案:

答案 0 :(得分:5)

a未被删除,它只是没有包含在**kwargs中,因为您在函数定义中明确定义了它。所以如果我编辑你原来的例子:

def my_func(a=4, **kwargs):
    print kwargs
    print a

然后测试一下:

>>> my_func(a=5, b=7)
{'b': 7}
5

**kwargs参数用于收集函数调用中给出的可选关键字参数,未明确包含在函数定义中。由于您在a=4的定义中加入了my_func,因此不会包含在**kwargs中。

Python documentation(强调我的)中提到了这一点:

  

当存在**形式的最终形式参数时,它   接收包含所有内容的字典(请参阅Mapping Types — dict)   关键字参数除了与形式参数相对应的参数。

答案 1 :(得分:1)

Python的参数映射似乎包括处理表达为“arg = value”表达式的任何参数,即使它们出现故障。这将删除包含在** kwargs字典中的“arg = value”对(它捕获不在参数列表中的所有名称/键)。

考虑这个简单的例子:

#/usr/bin/python
def foo(a, **d):
    print 'a=', a
    print 'd=', d

foo(z=1)
## TypeError: foo() takes exactly 1 argument (0 given)
foo(a=1)
## a= 1
## d= {}
foo(z=1, a=2, b=3)
## a= 2
## d= {'z':1, 'b':3}
foo(a=1, z=2, 3)
## SyntaxError: non-keyword arg after keyword arg

请注意,我已经使用位置参数实现了“foo”,并且没有默认参数;它有一个默认值然后“a =”仍然会从参数列表中选出,如果它出现,但它的遗漏不会引发异常,它将是“无”或你提供的任何默认参数。

区分参数和参数有时很有用。在常见的文档和在线讨论中很少遵循这种区别......所以它可能有点学术性。但是,参数是一个名称,在函数的定义/标题中提供,并且在调用函数时绑定参数。参数=占位符,参数=调用期间的实际值。有时进行这种区分可以使讨论,例如这种讨论更容易混淆。

在谈论def陈述本身时,会出现一点可能的混淆。在我的陈述中:def foo(a=None, **d) a和d是参数,而a=None**d是参数(对于define语句本身)。当中间Python程序员首次遇到实例化为函数定义中的参数的可变对象的语义时,这可能会特别令人困惑:def foo(mydict={}, mylist=[]): ...当使用和不使用参数调用时,这可能会有一些有趣的语义。理解这种函数的关键是mydict和mylist绑定到在定义函数时实例化的对象。只有在没有参数的情况下调用这些参数时,这些对象才可见,并且当在这些位置使用参数调用函数时,这些参数将绑定到其他对象。 (正如您所看到的,当使用术语“参数”与“参数”互换时,这个概念几乎不可能表达。)