好的,所以我想让你理解而不是仅仅给出答案,因为 StackOverflow 是关于解释概念而不是编写代码,让我们理解几点:
*args 和 **kwargs 用作任意数量的参数。
Kwargs ** 语法需要一个映射(比如字典);每个
映射中的键值对成为关键字参数。
而
*args 接收一个包含位置参数的元组。
现在让我们举个简单的例子来理解你的问题:
def check(*a,**b):
print(a)
print(b)
现在 *a 需要元组或列表或位置参数,而 **b 需要字典格式的关键字参数。
在进入问题之前还有一点:
*l 习惯用法是解包参数列表、元组、集合
a,*b=(1,2,3,4,5)
print(a)
print(b)
输出:
1
[2, 3, 4, 5]
现在,如果我将该函数称为:
def check(*a,**b):
print("value_a {}".format(a))
print("value_b {}".format(b))
print(check({'y': 5, 'x': 3, 'a': 5,'r':56}))
现在 *a 将采用该值,因为没有关键字参数:
value_a ({'x': 3, 'y': 5, 'a': 5, 'r': 56},)
但是让我们添加一些关键字参数:
print(check({'y': 5, 'x': 3, 'a': 5,'r':56},key_s=5,values=10))
输出:
value_a ({'a': 5, 'y': 5, 'r': 56, 'x': 3},)
value_b {'key_s': 5, 'values': 10}
让我们开始使用 unpack 方法:
print(check(*{'y': 5, 'x': 3, 'a': 5,'r':56}))
输出将是:
value_a ('r', 'x', 'y', 'a')
value_b {}
None
因为正如我所展示的,* 将解包 dict 的键,并将它们视为位置参数而不是关键字参数。
现在让我们使用 ** 解包,它将 dict 解包为键值对:
我想你明白了,现在让我们使用 ** 来映射字典,这样它将解压字典和每个键,值将是关键字参数:
print(check(**{'y': 5, 'x': 3, 'a': 5,'r':56}))
输出:
value_a ()
value_b {'y': 5, 'r': 56, 'a': 5, 'x': 3}
所以我想现在一切都清楚了。
现在让我们回到您的问题:
如你所说,如果你正在使用:
def check(a,**b):
print("value_a {}".format(a))
print("value_b {}".format(b))
print(check(**{'y': 5, 'x': 3, 'a': 5,'r':56}))
您得到结果是因为它从 dict 获取“a”值,而其余值由 **b 获取
现在如果你想使用 *a 和 **b 那么你必须提供:
the positional argument for *a
Keyworded argument for **b
正如你所说你不想修改 foo 那么你可以尝试这样的事情:
def bar (*a, **b):
foo((a,),**b)
def foo (*a, **c):
print(c)
print(a)
if __name__ == '__main__':
bar(2,3,4, x=3, y=5)
输出:
{'y': 5, 'x': 3}
(((2, 3, 4),),)