Python 如何在函数签名中返回带有*args和**kwargs的默认值

Python 如何在函数签名中返回带有*args和**kwargs的默认值,python,python-3.x,function,args,keyword-argument,Python,Python 3.x,Function,Args,Keyword Argument,我试图在Python3(Python3.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), {}) # W

我试图在Python3(Python3.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, (), {})
我不明白的是,第一个print语句中的
y=10发生了什么?我可以看到它被
args
中的
1
覆盖,但我不确定为什么

如何重写此函数以使默认值不被重写,或者在如何将参数从函数签名传递到return语句方面缺少了什么


我试着寻找,但没有找到我想要的答案。正如我所想,将默认值放在
args
kwargs
之前可以防止覆盖

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

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

您可以通过将
y
设为。通过将参数放在
*args
变量位置捕获所有参数之后,或者如果没有
*名称
参数,则将参数放在
*
单个星号之后:

def add_args(*args, y=10, **kwargs):
    return y, args, 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
关键字catch all:

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))
>>def add_args(*args,y):#仅限强制关键字参数
...     返回y,args
...
>>>添加参数(1,5,10,20,50)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:add_args()缺少1个仅限关键字的必需参数:“y”
>>>添加参数(1,5,10,20,50,y=42)
(42, (1, 5, 10, 20, 50))

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

您可以通过将
y
设为。通过将参数放在
*args
变量位置捕获所有参数之后,或者如果没有
*名称
参数,则将参数放在
*
单个星号之后:

def add_args(*args, y=10, **kwargs):
    return y, args, 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
关键字catch all:

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))
>>def add_args(*args,y):#仅限强制关键字参数
...     返回y,args
...
>>>添加参数(1,5,10,20,50)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:add_args()缺少1个仅限关键字的必需参数:“y”
>>>添加参数(1,5,10,20,50,y=42)
(42, (1, 5, 10, 20, 50))

如果您不想让调用者覆盖它,为什么它是一个参数?为什么不把
y=10
作为正文的第一行呢?请看下面我的答案,您检查的第一个链接上的公认答案确实正确地记录了这一点:将
y=10
放在
*args
捕获所有变量位置参数之后。如果您不想让调用者覆盖它,为什么它是一个参数?为什么不把
y=10
作为主体的第一行呢?请看下面我的答案,您检查的第一个链接上的公认答案确实正确地记录了这一点:将
y=10
放在
*args
捕获所有变量位置参数之后。啊,谢谢。我明白我错在哪里了。回答得很好,我很感谢你的回复。啊,谢谢。我明白我错在哪里了。回答得很好,我很感谢你的回答。