2014-09-03 46 views
1
def func(*v, **k): pass 
func(**{'a': 1}, *(1, 2, 3))  # ERROR... 
func(a=1, *(1, 2, 3))   # OK... 

我不明白为什么第一次不起作用,而第二次起作用。在函数调用中混合* vargs和** kargs参数

有人可以告诉“因为执行情况如此”,但我也想知道为什么的执行情况如此。为了使这个调用起作用,实现不能将第一个翻译成第二个?

+0

第二只工作,如果'了',是第4个定义的参数。 – chepner 2014-09-03 14:06:52

+0

你可以做'func(*(1,2,3),** {'a':1})''。语法只是指定'* args'在'** kwargs'之前。为什么?因为没关系,所以他们只是选择了一个订单。 – 2014-09-03 14:12:07

+0

@SvenMarnach Mmmmh ....这个解决方案背后不存在性能原因吗? – zer0uno 2014-09-03 23:03:50

回答

1

首先,第二行仅在a参数是最后一个(第四个)时起作用。例如,下面的代码将无法正常工作:

def func(a,b,c,d): 
    pass 

func(a=1, *(1, 2, 3)) 

而对于你的问题,我认为这个问题的第一行:

func(**{'a': 1}, *(1, 2, 3)) 

是,你可以有多个值相同的参数此方式,如果字典包含前3个参数之一。

不同的是,字典可以是可变的,并且对不同的运行不同的值,所以这段代码总是认为是非法的

+0

'func(*(1,2,3),** {'a':1}'是允许的,所以推理可能不是你猜到的。 – 2014-09-03 14:14:28

+0

有趣,谢谢。可能是因为它不清楚如果你把它放在开头,'a'是最后一个变量,或者只是因为参数顺序很重要,就像每次调用函数时一样,* vargs应该在** kargs之前(编辑:现在我看到你已经写了它在一个评论..) – Elisha 2014-09-03 14:22:31

1

像这样传递位置参数和关键字参数是语言语法的一部分,而不是运行时功能。也就是说,*(1,2,3)不会简单地创建一个特殊对象,该对象在被调用时被传递给该函数,并用于“以某种方式”将值分配给定义的参数。因此,在排序中允许这种灵活性会导致解析器复杂化,而没有真正的好处。