使用* args,** kwargs和optional / default参数调用Python函数

Calling a Python function with *args,**kwargs and optional / default arguments

在python中,我可以定义如下函数:

1
2
def func(kw1=None,kw2=None,**kwargs):
   ...

在这种情况下,我可以将func称为:

1
func(kw1=3,kw2=4,who_knows_if_this_will_be_used=7,more_kwargs=Ellipsis)

我还可以将函数定义为:

1
2
def func(arg1,arg2,*args):
    ...

可以称为

1
func(3,4,additional,arguments,go,here,Ellipsis)

最后,我可以把这两种形式结合起来

1
2
def func(arg1,arg2,*args,**kwargs):
    ...

但不起作用的是:

1
2
func(arg1,arg2,*args,kw1=None,kw2=None,**kwargs):  #SYNTAX ERROR (in python 2 only,  apparently this works in python 3)
    ...

我最初的想法是这可能是因为

1
2
def func(arg1,arg2,*args,kw1=None):
    ...

可以称为

1
func(1,2,3) #kw1 will be assigned 3

因此,这将引入一些关于3应该打包成args还是kwargs的模糊性。但是,使用python 3,可以指定只包含关键字的参数:

1
2
def func(a,b,*,kw=None):  #can be called as func(1,2), func(1,2,kw=3), but NOT func(1,2,3)
   ...

这样一来,似乎就没有以下方面的语法歧义:

1
2
def func(a,b,*args,*,kw1=None,**kwargs):
    ...

但是,这仍然会导致语法错误(用python3.2测试)。我失踪是不是有原因?还有,有没有一种方法可以获得我上面描述的行为(使用带有默认参数的*参数)——我知道我可以通过在函数内部操纵Kwargs字典来模拟这种行为。


在Python3中可以这样做。

1
def func(a,b,*args,kw1=None,**kwargs):

bare *仅在希望指定只包含关键字的参数而不接受带*args的可变数量位置参数时使用。你不使用两个*

从语法中引用,在python 2中,

1
2
3
4
parameter_list ::=  (defparameter",")*
                    ( "*" identifier [,"**" identifier]
                    |"**" identifier
                    | defparameter [","] )

在python 3中,您有

1
2
3
4
5
parameter_list ::=  (defparameter",")*
                    ( "*" [parameter] ("," defparameter)*
                    [,"**" parameter]
                    |"**" parameter
                    | defparameter [","] )

其中包括在*参数之后提供附加参数。

更新:

这里是最新的python 3文档。


如果要混合使用这两个参数,请记住,*args和**kwargs必须是最后指定的参数。

1
2
def func(arg1,arg2,*args,kw1=None,kw2=None,**kwargs): #Invalid
def func(arg1,arg2,kw1=None,kw2=None,*args,**kwargs): #Valid

这些注释似乎是基于混淆了如何构造函数定义,而不是将提供的参数分配回定义中指定的参数。

这是这个函数的定义,它有6个参数。它是通过在函数调用中向其传递命名和未命名参数来调用的。

对于这个例子…当一个参数在调用函数时被命名时,它可以被无序提供。arg1和arg2是强制参数,如果未作为命名参数传递给函数,则必须从提供的未命名参数中按顺序分配它们。kw1和kw2在函数定义中提供了默认值,因此它们不是强制的,但如果没有作为命名参数提供,它们将从其余提供的未命名参数中获取任何可用值。将为名为args的数组中的函数提供任何剩余的未命名参数。在函数定义中没有相应参数名的任何命名参数都将提供给名为kwargs的字典中的函数调用。