Python 如果存在同名的位置参数,为什么会删除kwargs中的键?

Python 如果存在同名的位置参数,为什么会删除kwargs中的键?,python,keyword-argument,Python,Keyword Argument,我刚刚遇到了让我吃惊的行为: def my_func(a=4, **kwargs): print kwargs 演示: 此外,如果我得到: SyntaxError:关键字参数重复 如 python删除关键字“a”遵循什么规则 也许我遗漏了一些明显的东西,或者一个关键的术语,但我无法通过搜索找到解决方案 a没有被删除,只是没有包含在**kwargs中,因为您在函数定义中明确定义了它。因此,如果我编辑您的原始示例: def my_func(a=4, **kwargs): print

我刚刚遇到了让我吃惊的行为:

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

此外,如果我得到:

SyntaxError:关键字参数重复

python删除关键字“a”遵循什么规则


也许我遗漏了一些明显的东西,或者一个关键的术语,但我无法通过搜索找到解决方案

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

def my_func(a=4, **kwargs):
    print kwargs
    print a
#/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
然后测试它:

>>> my_func(a=5, b=7)
{'b': 7}
5
使用
**kwargs
参数收集函数调用中给定的可选关键字参数,该函数调用中未明确包含在函数定义中。由于您将
a=4
包含在
my_func
的定义中,因此它不会包含在
**kwargs

这在(矿山重点)中提到:

当存在表单**名称的最终形式参数时,它 接收包含所有内容的字典(请参阅) 关键字参数与形式参数相对应的参数除外。


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

def my_func(a=4, **kwargs):
    print kwargs
    print a
#/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
然后测试它:

>>> my_func(a=5, b=7)
{'b': 7}
5
**kwargs
参数用于收集函数调用中给定的可选关键字参数,该参数未明确包含在函数定义中。由于您将
a=4
包含在
my_func
的定义中,因此它不会包含在
**kwargs

这在(矿山重点)中提到:

当存在表单**名称的最终形式参数时,它 接收包含所有内容的字典(请参阅) 关键字参数与形式参数相对应的参数除外。


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

考虑一下这个简单的例子:

def my_func(a=4, **kwargs):
    print kwargs
    print a
#/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
是参数(定义语句本身)。当中间Python程序员第一次遇到在函数定义中实例化为参数的可变对象的语义时,这可能会特别令人困惑:
def foo(mydict={},mylist=[]):
。。。当使用和不使用参数调用时,这可能会有一些有趣的语义。理解这类函数的关键是mydict和mylist绑定到在定义函数时实例化的对象。这些对象仅在调用函数时不带参数时可见,而在调用函数时带参数处于这些位置时,这些参数绑定到其他对象。(如您所见,当使用术语“argument”与“parameter”互换时,这个概念几乎不可能表达。)

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

考虑一下这个简单的例子:

def my_func(a=4, **kwargs):
    print kwargs
    print a
#/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
是参数(定义语句本身)。当中间Python程序员第一次遇到在函数定义中实例化为参数的可变对象的语义时,这可能会特别令人困惑:
def foo(mydict={},mylist=[]):
。。。这可能有一些有趣的语义