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

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

considerando quanto segue:Python 3.5 TypeError: got più valori per argomento

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

perché si comporta in questo modo?
Qualche ragione in particolare?

+1

Interessante, l'eccezione dà " ha ottenuto più valori per l'argomento di parole chiave 'a' "in python 2.7 e" ha ottenuto più valori per l'argomento 'b' "in python 3.5 – cdarke

+0

@cdarke Quando si usano argomenti di parole chiave ciò che accade è che python costruisce un' d ict' per memorizzare questi argomenti. 'Dict's non ha un ordine affidabile. La differenza nel messaggio di errore riflette questo: usando python2.7 succede che l'hash si comporti in modo che 'a' sia la prima chiave da iterare mentre su python3.5 succede a' b'. Ma dipende completamente da come viene costruito il dizionario, ecc. – Bakuriu

+0

@Bakuriu: ne ero consapevole, ma credo che ci sarebbe dovuto essere un po 'di sforzo per ottenere un messaggio di errore coerente e utile, indipendentemente dall'implementazione interna. Il problema "reale" consiste nell'utilizzare le parole chiave prima degli argomenti posizionali, e questo è l'errore che avrebbe dovuto essere rilevato e segnalato. – cdarke

risposta

5

Nella documentazione 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 .

E, questo è seguito da:

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).

(sottolineatura mia)

Così Python primo processo i *args come argomenti posizionali, assegnare un valore a b e riassegnarlo con b=5 risultante in un errore per l'argomento della parola chiave avente m valori multipli.

0

Il problema sono le parole chiave. Non sono ammessi argomenti posizionali dopo gli argomenti delle parole chiave.

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

funziona bene, nel senso che passa un tupla con i valori 1,2,3. Lo stesso che:

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

Le parole chiave devono sempre venire dopo argomenti posizionali, quindi è la vostra dichiarazione di funzione che non è corretto:

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

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

Dà:

(3, 5,()) 
(3, 5, (1, 2, 3)) 
Problemi correlati