2017-02-23 4 views
0

Ich habe verschiedene Methoden versucht, die Methode mit * args aufzurufen. Unten ist mein Codestück.Understanding TypeError: habe mehrere Werte für das Schlüsselwortargument erhalten

def total(name, *args): 
    if args: 
     print("%s has total money of Rs %d/- " %(name, sum(args))) 
    else: 
     print("%s's piggy bank has no money" %name) 

Jetzt gibt es zwei Möglichkeiten, diese Methode aufzurufen. Man übergibt die zusätzlichen Argumente innerhalb *() oder direkt durch Komma trennen. Ich übergebe Wert für 'Name' in Form von param = Wert, absichtlich, damit es mir Fehler wirft. Im Folgenden sind zwei Möglichkeiten, wie ich versuchte: -

1 - Passing die zusätzlichen params Komma getrennt: -

>>> total(name="Adi", 1, 2, 10) 
    File "<stdin>", line 1 
SyntaxError: non-keyword arg after keyword arg 

2 - Verwendung *() zusätzliche params weitergeben müssen: -

>>> total(name="Adi", *(1, 2, 10)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: total() got multiple values for keyword argument 'name' 

Die erste Fehlermeldung ist ziemlich klar und es vermittelt den genauen Fehler. Die Fehlermeldung für den zweiten Aufruf kann ich jedoch nicht verstehen.

Wie bewertet Python den zweiten Aufruf, dass es mehrere Werte für den Parameter 'Name' erhält? Die Möglichkeiten, die mir in den Sinn kam, wird intern würde Python

übersetzen werden

total(name="Adi", *(1, 2, 10))

wie folgt: -

total(*(1, 2, 10), name="Adi")

In dieser oben Übersetzung, wie pro Position, 'name' wird der Wert * (1 , 2,10) und später wird es "Adi". Also mehrere Werte Fehler wird verstanden.

Aber ich bin mir nicht sicher, ob Python intern die Positionen verändern würde? Jeder Einblick darauf wäre hilfreich.

+0

'total (Namen- "Adi", 1, 2, 10)' nicht gültig ist wegen das '-' Symbol. Sind Sie sicher, dass Sie uns den richtigen Code zeigen? –

+0

Mein schlechtes. war ein Fräulein. –

Antwort

1

Ich untersuchte die Methode mit inspect Modul. Die getcallargs()-Methode aus dem Inspect-Modul gibt Ihnen die Zuordnung der übergebenen Werte zu den Argumenten der Methode.

def total(name, *args): 
    if args: 
     print("%s has total money of Rs %d/- " %(name, sum(args))) 
    else: 
     print("%s's piggy bank has no money" %name) 

#total(name="Adi", *(1, 2, 10)) 
# equivalent call using inspect module 
import inspect 
print inspect.getcallargs(total, 'Adi', *(1, 2, 10)) 

Also, wenn ein Anruf auf ein Verfahren hergestellt wird, werden alle geht übergebenen Argumente in einem der folgenden zwei Formen

*positional :- a tuple of all positional arguments (without keyword) and arguments passed within *() or the extra non-keyworded arguments

**named :- a dictionary of all the arguments passed in form of param=value, and extra keyworded arguments

Also in meinem Anruf total(name="Adi", *(1, 2, 10)), 'positional' Tupel-Wert (1, 2,10) und 'named' Wörterbuch hat Wert {'Name': 'Adi'}

Dann tut es die Zuordnung der Werte zu den Argumenten. Während der Zuweisung werden Zwangsargumente zuerst zugewiesen. Python überprüft die Liste der obligatorischen Argumente (hier ['name']) und ordnet den Wert aus dem Tupel 'positional' der Reihe nach zu. Alle Werte aus dem nicht zugewiesenen Tupel werden als zusätzliche Parameter (nicht keywworded Argumente) angenommen.

Damit erhält der Parameter 'name' den Wert 1 zugewiesen. Und die verbleibenden Werte (d. H. 2 und 10) werden als zusätzliche Parameter angenommen.

Als nächstes überprüft es, ob die Methode nicht-keyworded Argumente in seiner Signatur hat. Wenn dies der Fall ist, werden die verbleibenden Werte von 'positional' Tupel demselben zugewiesen. Also wird hier 'args' den verbleibenden Werten zugewiesen, d. H. Tupel von (2,10).

aber, wenn es keine Nicht-Schlüsselwort Argumente Methodensignatur ist und 'positional' Tupel einige Werte noch unver zugewiesen hat, dann

Python führt den Fehler „Methode nimmt genau X Argumente Y gegeben“ Y größer als X ist,

Sobald alle Werte von 'positional' zugewiesen sind, wird die Zuweisung der Werte aus dem 'named' Wörterbuch zugewiesen. In diesem Fall prüft der Interpreter zuerst, ob eines der Zwangsargumente im Wörterbuch vorhanden ist, d. H. Ob Werte zu irgendeinem der Zwangsargumente in Form von <param=value> im Methodenaufruf übergeben werden? Wenn ja, dann prüft es als nächstes, ob diesen Zwangsargumenten bei der Zuweisung von Werten aus 'positional' Tupel ein Wert zugewiesen wurde.

Wenn ja, dann findet es zwei Werte für das gleiche Argument (eine von 'positional' und die andere von 'named') und wirft daher "got multiple values for keyword argument" Fehler. Andernfalls weist er dem Argument den Wert 'named' zu.

Auf diese Weise wird in dem obigen Fall Argument ist 'name' obligatorische Argument und ist in 'named' Wörterbuch vorhanden, wie ich name="Adi" im Methodenaufruf übergeben haben. Bei der Zuweisung von Positionswerten (Werte von 'positional' Tupel) wird der Variablen 'name' der Wert 1 zugewiesen. Und aus dem Wörterbuch der benannten Argumente (Werte aus 'named' Wörterbuch), hat es den Wert 'Adi' gehen, die 2 Werte zu der Variablen 'name' zugeordnet wird. Daher werden wir den Fehler bekommen: -

total() got multiple values for keyword argument 'name'

Daher wird, während nicht-keyworded zusätzliche Argumente zu übergeben, muss man nur den Wert für die obligatorische Argumente übergeben, die es Positions machen. Aber, nicht in Form von <param=val>, die es benannt wird und zwei Werte für den Parameter erhalten wird daher den Fehler werfen. Daher ist es nicht empfehlenswert, die obligatorischen Argumente in Form von <param = value > zu übergeben.

So die richtigen Möglichkeiten, um die Methode aufzurufen sind: -

total('Adi', *(1,2,10))

oder

total('Adi', 1, 2, 10)

Verwandte Themen