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

问题描述 投票:57回答:2

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

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

在这种情况下,我可以调用func作为:

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

我也可以定义一个函数:

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

可称为

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

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

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

但是,什么是行不通的是:

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

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

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

可以称为

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

因此,这将引入一些含糊不清的关于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)
   ...

有了这个,似乎没有语法模糊:

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

但是,这仍然会导致语法错误(使用Python3.2测试)。这是否有理由让我失踪?并且,有没有办法获得我上面描述的行为(使用默认参数* args) - 我知道我可以通过操作函数内部的kwargs字典来模拟该行为。

python python-3.x syntax kwargs
2个回答
58
投票

你可以在Python 3中做到这一点。

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

仅当您想要指定仅关键字参数而不接受*的可变数量的位置参数时,才使用裸*args。你不使用两个*s。

引用语法,在Python 2,你有

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

而在Python 3,你有

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

其中包括*参数之后的附加参数的规定。

更新:

最新的Python 3文档here


6
投票

如果你想混合两者,记住* args和** kwargs必须是指定的最后一个参数。

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的字典中的函数调用。

© www.soinside.com 2019 - 2024. All rights reserved.