2014-09-03 50 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)不會簡單地創建一個特殊對象,該對象在被調用時被傳遞給該函數,並用於「以某種方式」將值分配給定義的參數。因此,在排序中允許這種靈活性會導致解析器複雜化,而沒有真正的好處。