使用*args、*kwargs和可选/默认参数调用Python函数

时间:2022-01-25 11:00:36

In python, I can define a function as follows:

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

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

In this case, i can call func as:

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

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

I can also define a function as:

我还可以将函数定义为:

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

which can be called as

哪一个可以称为as

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

Finally, I can combine the two forms

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

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

But, what does not work is calling:

但是,没有起作用的是:

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

My original thought was that this was probably because a function

我最初的想法是,这可能是因为一个函数

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

can be called as

可以被称为

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

So this would introduce some ambiguity as to whether 3 should be packed into args or kwargs. However, with python 3, there is the ability to specify keyword only arguments:

所以这就引入了一些模棱两可的东西关于3应该被打包成args还是kwargs。但是,使用python 3,有能力只指定关键字参数:

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

With this, it seems that there is no syntactic ambiguity with:

有了这个,似乎没有语法上的歧义:

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

However, this still brings up a syntax error (tested with Python3.2). Is there a reason for this that I am missing? And, is there a way to get the behavior I described above (Having *args with default arguments) -- I know I can simulate that behavior by manipulating the kwargs dictionary inside the function.

但是,这仍然会带来语法错误(使用Python3.2进行测试)。有什么原因让我错过?而且,是否有一种方法可以获得我上面描述的行为(拥有带有默认参数的*args)——我知道我可以通过在函数内部操作kwargs字典来模拟这种行为。

2 个解决方案

#1


48  

You can do that on Python 3.

在Python 3中可以这样做。

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

The bare * is only used when you want to specify keyword only arguments without accepting a variable number of positional arguments with *args. You don't use two *s.

bare *仅在需要指定关键字参数时才使用,而不接受带有*args的可变数量的位置参数。你不用两个*。

To quote from the grammar, in Python 2, you have

在Python 2中引用语法,您有。

parameter_list ::=  (defparameter ",")*
                    (  "*" identifier [, "**" identifier]
                    | "**" identifier
                    | defparameter [","] )

while on Python 3, you have

在Python 3中,您有

parameter_list ::=  (defparameter ",")*
                    (  "*" [parameter] ("," defparameter)*
                    [, "**" parameter]
                    | "**" parameter
                    | defparameter [","] )

which includes a provision for additional parameters after the * parameter.

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

#2


6  

If you want to do a mixture of both remember that *args and **kwargs must be the last parameters specified.

如果您想同时使用*args和*kwargs,请记住它们必须是最后指定的参数。

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

The comments seem to be based on mixing up how a function definition is constructed compared to how the arguments provided are assigned back to the parameters specified in the definition.

注释似乎是基于将函数定义的构造方式与提供的参数分配给定义中指定的参数的方式混合在一起。

This is the definition of this function which has 6 parameters. It is called by passing named and unnamed arguments to it in a function call.

这个函数有6个参数。通过在函数调用中向它传递命名参数和未命名参数来调用它。

For this example... When an argument is named when calling the function it can be provided out of order. arg1 and arg2 are mandatory parameters and if not passed to the function as named arguments, then they must be assigned in order from the provided unnamed arguments. kw1 and kw2 have default values provided in the function definition so they are not mandatory, but if not provided for as named arguments they will take any available values from the remaining provided unnamed arguments. Any unnamed arguments left over are provided to the function in an array called args Any named arguments that do not have a corresponding parameter name in the function definition are provided to the function call in a dictionary called kwargs.

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

#1


48  

You can do that on Python 3.

在Python 3中可以这样做。

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

The bare * is only used when you want to specify keyword only arguments without accepting a variable number of positional arguments with *args. You don't use two *s.

bare *仅在需要指定关键字参数时才使用,而不接受带有*args的可变数量的位置参数。你不用两个*。

To quote from the grammar, in Python 2, you have

在Python 2中引用语法,您有。

parameter_list ::=  (defparameter ",")*
                    (  "*" identifier [, "**" identifier]
                    | "**" identifier
                    | defparameter [","] )

while on Python 3, you have

在Python 3中,您有

parameter_list ::=  (defparameter ",")*
                    (  "*" [parameter] ("," defparameter)*
                    [, "**" parameter]
                    | "**" parameter
                    | defparameter [","] )

which includes a provision for additional parameters after the * parameter.

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

#2


6  

If you want to do a mixture of both remember that *args and **kwargs must be the last parameters specified.

如果您想同时使用*args和*kwargs,请记住它们必须是最后指定的参数。

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

The comments seem to be based on mixing up how a function definition is constructed compared to how the arguments provided are assigned back to the parameters specified in the definition.

注释似乎是基于将函数定义的构造方式与提供的参数分配给定义中指定的参数的方式混合在一起。

This is the definition of this function which has 6 parameters. It is called by passing named and unnamed arguments to it in a function call.

这个函数有6个参数。通过在函数调用中向它传递命名参数和未命名参数来调用它。

For this example... When an argument is named when calling the function it can be provided out of order. arg1 and arg2 are mandatory parameters and if not passed to the function as named arguments, then they must be assigned in order from the provided unnamed arguments. kw1 and kw2 have default values provided in the function definition so they are not mandatory, but if not provided for as named arguments they will take any available values from the remaining provided unnamed arguments. Any unnamed arguments left over are provided to the function in an array called args Any named arguments that do not have a corresponding parameter name in the function definition are provided to the function call in a dictionary called kwargs.

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