我刚遇到这种让我感到惊讶的行为:
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'?
也许我错过了一些明显的或关键的术语,但我无法通过搜索找到解决方案。
答案 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绑定到在定义函数时实例化的对象。只有在没有参数的情况下调用这些参数时,这些对象才可见,并且当在这些位置使用参数调用函数时,这些参数将绑定到其他对象。 (正如您所看到的,当使用术语“参数”与“参数”互换时,这个概念几乎不可能表达。)