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

Che*_*075 1 python function args keyword-argument python-3.x

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

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

def add_args(y=10, *args, **kwargs):
    return y, args, kwargs
Run Code Online (Sandbox Code Playgroud)

并测试它以查看返回的内容:

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

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

我怎样才能重写这个函数,这样默认值就不会被覆盖,或者我是否遗漏了参数从函数签名传递到 return 语句的方式?

我试着在这里这里寻找,但没有找到我正在寻找的答案。因为我认为将默认值放在args和之前kwargs会防止覆盖。

Mar*_*ers 5

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

您可以y通过将其设置为仅关键字参数来防止被用作位置参数。您可以通过将参数放在var-positional catch-all 参数之后来实现*args,或者如果您没有*name参数,则在*单个星号之后:

def add_args(*args, y=10, **kwargs):
    return y, args, kwargs
Run Code Online (Sandbox Code Playgroud)

或者

def keyword_only_args(*, y=10, **kwargs):
    return y, kwargs
Run Code Online (Sandbox Code Playgroud)

现在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), {})
Run Code Online (Sandbox Code Playgroud)

你也不必有一个**kwargs关键字包罗万象:

def add_args(*args, y=10):
    return y, args
Run Code Online (Sandbox Code Playgroud)

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

仅关键字参数不必具有默认值,=10可以省略,但随后参数变为必需,并且只能在调用中使用y=value以下方法指定:

>>> 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))
Run Code Online (Sandbox Code Playgroud)