Was bedeutet dict.pop (a, b) in Python?

90
class a(object):
    data={'a':'aaa','b':'bbb','c':'ccc'}
    def pop(self, key, *args):
            return self.data.pop(key, *args)#what is this mean.

b=a()
print b.pop('a',{'b':'bbb'})
print b.data

self.data.pop(key, *args) ← ------ warum gibt es ein zweites Argument?

zjm1126
quelle
8
Oder wenn Sie help(b.data.pop)in der REPL wirklich faul sind .
Michael Mior

Antworten:

119

Das popVerfahren von dicts (wie self.data, das heißt {'a':'aaa','b':'bbb','c':'ccc'}, hier) zwei Argumente - siehe die Dokumentation

Das zweite Argument defaultgibt popzurück, wenn das erste Argument keyfehlt. (Wenn Sie popmit nur einem Argument aufrufen , keywird eine Ausnahme ausgelöst, wenn dieser Schlüssel fehlt.)

In Ihrem Beispiel print b.pop('a',{'b':'bbb'})ist dies unerheblich , da 'a' ist ein Schlüssel in b.data. Aber wenn Sie diese Zeile wiederholen ...:

b=a()
print b.pop('a',{'b':'bbb'})
print b.pop('a',{'b':'bbb'})
print b.data

Sie werden sehen, dass es einen Unterschied macht: Der erste popentfernt den 'a'Schlüssel, so dass im zweiten popdas defaultArgument tatsächlich zurückgegeben wird (da 'a'es jetzt nicht mehr vorhanden ist b.data).

Alex Martelli
quelle
3
Nur ein kleiner kleiner Kommentar, der meiner Meinung nach in einigen Situationen wichtig ist, in denen der Benutzer popein Element von benötigt, dictaber den Wert des gepoppten Elements beibehält. So dict.pop(key)entfernt die keyzusammen mit dem zugehörigen , valuesondern auch gibt die valuevon der , keydie gerade entfernt wurde. Ich fand es nützlich ...
Flamenco
@flamenco das ist, was ich von pop()- allgemeinem Verhalten in mehr Sprachen wie JavaScript, PHP, Java erwarte , obwohl dies nicht alle Sprachen tun - zB C ++.
jave.web
27

So viele Fragen hier. Ich sehe mindestens zwei, vielleicht drei:

  • Was macht Pop (a, b)? / Warum gibt es ein zweites Argument?
  • Wofür wird *argsverwendet?

Die erste Frage wird in der Python Standard Library- Referenz trivial beantwortet :

Pop (Taste [, Standard])

Wenn sich der Schlüssel im Wörterbuch befindet, entfernen Sie ihn und geben Sie seinen Wert zurück. Andernfalls geben Sie den Standardwert zurück. Wenn die Standardeinstellung nicht angegeben ist und der Schlüssel nicht im Wörterbuch enthalten ist, wird ein KeyError ausgelöst.


Die zweite Frage wird in der Python-Sprachreferenz behandelt :

Wenn das Formular "* identifier" vorhanden ist, wird es mit einem Tupel initialisiert, das überschüssige Positionsparameter empfängt, wobei standardmäßig das leere Tupel verwendet wird. Wenn das Formular "** bezeichner" vorhanden ist, wird es mit einem neuen Wörterbuch initialisiert, das überschüssige Schlüsselwortargumente empfängt, wobei standardmäßig ein neues leeres Wörterbuch verwendet wird.

Mit anderen Worten, die popFunktion akzeptiert mindestens zwei Argumente. Den ersten beiden werden die Namen zugewiesen selfund key; und der Rest wird in ein Tupel namens gestopft args.

Was in der nächsten Zeile *argspassiert , wenn es im Aufruf an weitergegeben self.data.popwird , ist das Gegenteil davon - das Tupel *argswird auf Positionsparameter erweitert, die weitergegeben werden. Dies wird in der Python-Sprachreferenz erläutert :

Wenn der Syntax * -Ausdruck im Funktionsaufruf angezeigt wird, muss der Ausdruck zu einer Sequenz ausgewertet werden. Elemente aus dieser Sequenz werden so behandelt, als wären sie zusätzliche Positionsargumente

Kurz gesagt, a.pop()möchte flexibel sein und eine beliebige Anzahl von Positionsparametern akzeptieren, damit diese unbekannte Anzahl von Positionsparametern an weitergegeben werden kann self.data.pop().

Dies gibt Ihnen Flexibilität; dataist gerade ein dictund self.data.pop()nimmt entweder einen oder zwei Parameter; Wenn Sie sich jedoch datain einen Typ ändern würden , der 19 Parameter für einen Aufruf benötigt, self.data.pop()müssten Sie die Klasse aüberhaupt nicht ändern . Sie müssten jedoch jeden Code ändern, der aufgerufen wurde a.pop(), um die erforderlichen 19 Parameter zu übergeben.

James Polley
quelle
2
+1 für den Aufwand. Ich befürchte, dass das Englisch des OP nicht der Aufgabe gewachsen ist, Ihre Antwort zu lesen.
mechanisches
Ich habe das geschrieben, bevor ich das OP-Profil gelesen habe. Ich habe jetzt das besagte Profil gelesen und einige andere Fragen der OP gesehen. Ich habe gerade einen weiteren Versuch unternommen, diesmal nur mit Code :)
James Polley
6
>>> def func(a, *args, **kwargs):
...   print 'a %s, args %s, kwargs %s' % (a, args, kwargs)
... 
>>> func('one', 'two', 'three', four='four', five='five')
a one, args ('two', 'three'), kwargs {'four': 'four', 'five': 'five'}

>>> def anotherfunct(beta, *args):
...   print 'beta %s, args %s' % (beta, args)
... 
>>> def func(a, *args, **kwargs):
...   anotherfunct(a, *args)
... 
>>> func('one', 'two', 'three', four='four', five='five')
beta one, args ('two', 'three')
>>> 
James Polley
quelle
1
Ich habe mehrere Fragen gelesen, wie in meiner anderen Antwort beschrieben. Ich habe auch das OP-Profil gelesen und festgestellt, dass meine andere Antwort nutzlos ist. Diese Antwort sollte zumindest einen Teil dessen zeigen, was * args tut. Ich vermute, dass die OP trotz des Themas wirklich verwirrt ist.
James Polley
@ James, +1 für den zusätzlichen Aufwand. Ich war zu dem gleichen Schluss über die eigentliche Frage gekommen.
Peter Hansen
5
def func(*args): 
    pass

Wenn Sie eine Funktion auf diese Weise definieren, *argswird ein Array von Argumenten an die Funktion übergeben. Auf diese Weise kann Ihre Funktion funktionieren, ohne vorher zu wissen, wie viele Argumente an sie übergeben werden.

Sie tun dies auch mit Schlüsselwortargumenten, indem Sie Folgendes verwenden **kwargs:

def func2(**kwargs): 
    pass

Siehe: Beliebige Argumentlisten


In Ihrem Fall haben Sie eine Klasse definiert, die sich wie ein Wörterbuch verhält. Die dict.popMethode ist definiert als pop(key[, default]).

Ihre Methode verwendet den defaultParameter nicht. Indem Sie Ihre Methode mit definieren *argsund an übergeben *args, dict.pop()können Sie dem Aufrufer erlauben, den defaultParameter zu verwenden.

Mit anderen Worten, Sie sollten in der Lage sein, die popMethode Ihrer Klasse wie folgt zu verwenden dict.pop:

my_a = a()
value1 = my_a.pop('key1')       # throw an exception if key1 isn't in the dict
value2 = my_a.pop('key2', None) # return None if key2 isn't in the dict
Seth
quelle