Python:通过调用方法将Dictionary转换为Tuple隐式

时间:2018-06-06 15:41:49

标签: python dictionary tuples optional-parameters optional-arguments

我在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。

2 个答案:

答案 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),),)