我在Mininet开源项目中遇到Code的问题。我将它抽象为以下场景:
def bar (*a, **b):
b.update({'a':(a,)})
foo(**b)
def foo (*a, **c):
print(c)
print(a)
if __name__ == '__main__':
bar(2,3,4, x=3, y=5)
方法栏只是创建foo函数调用的助手。 如果我运行它,print(a)没有输出,因为值仍然存储在字典b中。如果我将* a更改为a,则可以正常工作。
这是我的问题: 是否有可能不修改Method foo,它将数据放入* a with data并且foo的调用就像第3行?这意味着只允许修改方法栏中的b。
答案 0 :(得分:0)
我不认为可以遵守您的条件。
如果方法foo
保持不变,则参数*a
表示没有名称的参数的列表(例如示例中的bar(2,3,4)
)。第3行中对foo(**b)
的调用意味着传递关键字args(例如示例中的bar(x=3, y=5)
),因此它们将传递给**c
,因为它是foo
中的关键字参数。
答案 1 :(得分:0)
好的,所以我想让你明白而不只是给出答案,因为StackOverflow完全是为了解释概念而不是编写代码,让我们理解几点:
* args和** kwargs用作任意数量的参数。
Kwargs **语法需要映射(例如字典);每 映射中的键值对成为关键字参数。
,
* args收到一个包含位置参数的元组。
现在让我们举一个简单的例子来理解你的问题:
def check(*a,**b):
print(a)
print(b)
现在* a需要一个元组或列表或位置参数,而** b需要dict格式的keyworded参数。
在讨论这个问题之前还有一点:
* l idiom是解包参数列表,元组,集合
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将取值,因为没有keyworded参数:
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的键,它会将它们视为位置参数而不是keyworded参数。
现在让我们使用**解包,将解包dict作为键值对:
我认为你明白了,现在让我们使用**来映射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),),)