我正在尝试在Python 3(Python 3.7.0)中使用args
和kwargs
来解决问题,但我的理解却遇到了一些问题。
这是我拥有的一个简单功能:
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语句的内容?
答案 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))