2016-07-07 41 views
5
def f(a, b, *args): 
    return (a, b, args) 

f(a=3, b=5) 
(3, 5,()) 

而多個值:的Python 3.5類型錯誤:得到了論證

f(a=3, b=5, *[1,2,3]) 
TypeError: got multiple values for argument 'b' 

爲什麼它的行爲這樣的嗎?
有什麼特別的原因?

+1

有趣的是,除了給出「在Python 2.7中爲關鍵字參數「a」獲得了多個值,並且在python 3.5中獲得了多個值「b'」 – cdarke

+0

@cdarke當使用關鍵字參數時,會發生什麼是python會生成一個'd ict'來存儲這些參數。 '字典沒有可靠的順序。錯誤信息的差異反映了這一點:使用python2.7它發生了這樣的情況:在python3.5中,'a'是第一個要迭代的關鍵字,它恰好是'b'。但它完全取決於如何建立字典等。 – Bakuriu

+0

@Bakuriu:我意識到這一點,但我覺得應該有一些努力獲得一致和有用的錯誤消息,無論內部實現。 「真正」的問題是在位置參數之前使用關鍵字,這就是應該檢測和報告的錯誤。 – cdarke

回答

5

在文檔for calls:

If the syntax *expression appears in the function call, expression must evaluate to an iterable. Elements from these iterables are treated as if they were additional positional arguments. For the call f(x1, x2, *y, x3, x4) , if y evaluates to a sequence y1, ..., yM , this is equivalent to a call with M+4 positional arguments x1, x2, y1, ..., yM, x3, x4 .

而且,這是其次:

A consequence of this is that although the *expression syntax may appear after explicit keyword arguments, it is processed before the keyword arguments (and any **expression arguments – see below).

(重點煤礦)

所以Python會先處理*args的位置參數,分配值設置爲b,並將其重新分配給b=5,導致關鍵字參數的錯誤爲m多重值。

0

問題是關鍵字。關鍵字參數後面不允許使用位置參數。

f(3, 5, *[1,2,3]) 

工作正常,因爲它傳遞一個元組值1,2,3。同爲:

f(3, 5, *(1,2,3)) 

關鍵詞必須總是放在位置參數之後,所以它是你的函數聲明這是不正確的:

def f(*args, a, b): 
    return (a, b, args) 

print(f(a=3, b=5)) 
print(f(*[1,2,3], a=3, b=5)) 

給出:

(3, 5,()) 
(3, 5, (1, 2, 3)) 
相關問題