如何在函数签名中使用* args和** kwargs返回默认值

时间:2018-09-11 21:03:26

标签: python python-3.x function args kwargs

我正在尝试在Python 3(Python 3.7.0)中使用argskwargs来解决问题,但我的理解却遇到了一些问题。

这是我拥有的一个简单功能:

def add_args(y=10, *args, **kwargs):
    return y, args, kwargs

并对其进行测试以查看返回的结果:

    print(add_args(1, 5, 10, 20, 50))
    print(add_args())
    >>
    (1, (5, 10, 20, 50), {}) # What happened to my default y=10?
    (10, (), {})

我不明白的是,第一份印刷声明中y=10发生了什么?我可以看到它被1中的args覆盖了,但是我不确定为什么。

如何重写此函数,以便不覆盖默认值,还是我缺少一些有关如何将参数从函数签名传递到return语句的内容?

我尝试查找herehere,但找不到所需的答案。我认为将默认值放在argskwargs之前可以防止覆盖。

2 个答案:

答案 0 :(得分:2)

嗯,y是函数定义中的第一个位置参数,因此很自然地它将绑定到调用站点上的第一个实际位置参数,即1。

答案 1 :(得分:2)

*args仅捕获其他未定义的位置参数; y=10并不意味着y不能用作位置参数。因此y被分配了第一个位置参数。

通过将y设置为keyword-only argument,可以防止将*args用作位置参数。为此,您可以将参数放置在*name var-positional-all参数之后,或者如果没有*参数,则将参数放在{{1}之后}单个星号:

def add_args(*args, y=10, **kwargs):
    return y, args, kwargs

def keyword_only_args(*, y=10, **kwargs):
    return y, kwargs

现在y将不再捕获位置参数:

>>> def add_args(*args, y=10, **kwargs):
...     return y, args, kwargs
...
>>> add_args(1, 5, 10, 20, 50)
(10, (1, 5, 10, 20, 50), {})          # y is still 10
>>> add_args(1, 5, 10, 20, 50, y=42)  # setting y explicitly 
(42, (1, 5, 10, 20, 50), {})

您也不必全部使用**kwargs关键字:

def add_args(*args, y=10):
    return y, args

但如果存在,则需要在最后列出。

仅关键字参数不必具有默认值,=10可以省略,但是随后该参数成为必需参数,并且只能在调用中使用y=value指定:< / p>

>>> def add_args(*args, y):  # mandatory keyword-only argument
...     return y, args
...
>>> add_args(1, 5, 10, 20, 50)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add_args() missing 1 required keyword-only argument: 'y'
>>> add_args(1, 5, 10, 20, 50, y=42)
(42, (1, 5, 10, 20, 50))