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

新手上路,请多包涵

在 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 是否应该打包到 argskwargs 中,这会引起一些歧义。但是,使用 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 函数内部的字典来模拟该行为。

原文由 mgilson 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 884
2 个回答

可以 在 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 文档 在这里

原文由 agf 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果您想混合使用两者,请记住 *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 的字典中提供给函数调用。

原文由 frank 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题