如何在函数签名中使用 *args 和 **kwargs return 默认值
How to return default values with *args, and **kwargs in function signature
我正在尝试在 Python 3 (Python 3.7.0) 中使用 args
和 kwargs
,但我 运行 进入一些我理解的问题。
这是我的一个简单函数:
def add_args(y=10, *args, **kwargs):
return y, args, kwargs
并测试它以查看 returned:
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
覆盖,但我不确定为什么。
我如何重写此函数以便不覆盖默认值,或者我是否遗漏了有关参数如何从函数签名传递到 return 语句的内容?
我尝试寻找 here and here 但没有找到我想要的答案。正如我所想的那样,将默认值放在 args
和 kwargs
之前可以防止覆盖。
嗯,y
是函数定义中的第一个位置参数,因此它自然会绑定到调用点的第一个实际位置参数,即 1。
*args
仅捕获任何未另行定义的位置参数; y=10
并不意味着 y
不能用作位置参数。所以 y
被分配了第一个位置参数。
您可以通过将 y
设为 keyword-only argument 来防止将其用作位置参数。您可以通过将参数 放在 之后 *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))
我正在尝试在 Python 3 (Python 3.7.0) 中使用 args
和 kwargs
,但我 运行 进入一些我理解的问题。
这是我的一个简单函数:
def add_args(y=10, *args, **kwargs):
return y, args, kwargs
并测试它以查看 returned:
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
覆盖,但我不确定为什么。
我如何重写此函数以便不覆盖默认值,或者我是否遗漏了有关参数如何从函数签名传递到 return 语句的内容?
我尝试寻找 here and here 但没有找到我想要的答案。正如我所想的那样,将默认值放在 args
和 kwargs
之前可以防止覆盖。
嗯,y
是函数定义中的第一个位置参数,因此它自然会绑定到调用点的第一个实际位置参数,即 1。
*args
仅捕获任何未另行定义的位置参数; y=10
并不意味着 y
不能用作位置参数。所以 y
被分配了第一个位置参数。
您可以通过将 y
设为 keyword-only argument 来防止将其用作位置参数。您可以通过将参数 放在 之后 *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))