【问题标题】:How to return default values with *args, and **kwargs in function signature [duplicate]如何在函数签名中使用 *args 和 **kwargs 返回默认值 [重复]
【发布时间】:2018-09-11 21:03:26
【问题描述】:

我正在尝试在 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 发生了什么?我可以看到它被args 中的1 覆盖,但我不确定为什么。

如何重写此函数以使默认值不被覆盖,或者我是否遗漏了参数如何从函数签名传递到返回语句的某些内容?

我尝试查找herehere,但没有找到我想要的答案。正如我认为将默认值放在argskwargs 之前可以防止覆盖。

【问题讨论】:

  • 如果你不希望它被调用者覆盖,为什么它是一个参数呢?为什么不把y=10 作为正文的第一行?
  • 在下面查看我的答案,您检查的第一个链接上接受的答案确实正确记录了这一点:将y=10 after *args catch-all var-positional 参数.

标签: python python-3.x function args keyword-argument


【解决方案1】:

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

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

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 指定:

>>> 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))

【讨论】:

  • 啊,谢谢。我知道我哪里出错了。很好的答案,我很感激你的回应。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 2018-07-13
    • 2015-01-28
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多