Wie heißt ** in Python?

59

Beim Programmieren von Python mache ich manchmal **eine Konvertierung. Ich verstehe, was es tut, aber welche Datenstrukturen bearbeite ich? A dictund was ist der andere? Ein array? Gibt es einen Namen für den **Betreiber?

Niklas Rosencrantz
quelle
3
Exponentialoperator?
Turm
12
Es gibt zwei Bedeutungen für **. Macht und "Keyword-Argument-Wörterbuch". Über was redest du? Die Dokumentation enthält die folgenden Wörter: "Wenn das Formular" ** bezeichner "vorhanden ist, wird es mit einem neuen Wörterbuch initialisiert, das alle überzähligen Schlüsselwortargumente empfängt. Standardmäßig wird ein neues leeres Wörterbuch verwendet." Welche davon scheinen für Ihre Frage relevant zu sein?
S.Lott
Ich habe nach "keyword argument dictionary" gefragt. Vielen Dank für die Kommentare.
Niklas Rosencrantz

Antworten:

86

Es ist kein Operator als solcher, hat also eigentlich keinen Namen, ist aber als "syntaktische Regel" definiert . Also sollte es heißen:

  • "das schlüsselwort argument entpacken syntax"

Wenn Sie eine Liste von Argumenten haben, *args, nennt man das „Argument auspacken“ , auf die gleiche Weise **kwargsheißt „Schlüsselwort - Argument Auspacken“ .

Wenn Sie es auf der linken Seite eines =wie in verwenden a, *middle, end = my_tuple, würden Sie "Tupel auspacken" sagen .

Insgesamt gibt es drei Arten von (Einzelparameter-) Argumenten:

def f(x)  # x: positional argument
def f(x, y=0)  # y: keyword argument
def f(x, *xs, y=0)  # y: keyword-only argument

Das *argsArgument heißt "variabler Positionsparameter" und **kwargsist der "variable Schlüsselwortparameter". Nur-Schlüsselwort-Argumente können nicht positionsbezogen angegeben werden, da ein variabler Positionsparameter alle von Ihnen übergebenen Argumente akzeptiert.

Das meiste davon finden Sie in den PEPs 0362 und 3102 sowie im Abschnitt Kontrollfluss in den Dokumenten. Es sollte jedoch beachtet werden, dass das Funktionssignaturobjekt PEP nur ein Entwurf ist und die Terminologie möglicherweise nur eine Idee einer Person ist. Aber sie sind trotzdem gute Begriffe. :)

Die Argumente *und **entpacken also einfach ihre jeweiligen Datenstrukturen:

args = (1, 2, 3)  # usually a tuple, always an iterable[1]

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

# and 

kwargs = {"a": 1, "b": 2, "c": 3}  # usually a dict, always a mapping*

f(**kwargs) -> f(a=1, b=2, c=3)

[1]: Iterables sind Objekte, die die __iter__()Methode implementieren , und Mappings sind Objekte, die keys()und implementieren __getitem__(). Alle Objekte, die dieses Protokoll unterstützen, werden von den Konstruktoren verstanden tuple()und dict()können daher zum Entpacken von Argumenten verwendet werden.

Stefano Palazzo
quelle
3
Falls jemand anderes verwirrt ist, def f(x, *xs, y=0): passist die Syntax von Python 2. {5,6,7} nicht gültig, und es wird auch nicht das def f(x, y=0, *xs):getan, was Sie vielleicht erwarten. AFAIK ist der einzige Weg, um die (offensichtlich) beabsichtigte Wirkung zu erzielen def f(x, *xs, **kw): y=kw.get('y', 0); del kw; .... Python 3 behandelt die ursprüngliche Syntax wie erwartet.
Chbrown
1
Während wir gerade dabei sind: Die begin, *middle, end = (0, 1, 2, 3, 4, 5)Syntax funktioniert auch in Python 2.x nicht.
Stefano Palazzo
Diese Antwort ist in Python 3.5 und höher falsch. PEP-448 gibt den Operator ** als Operator zum Entpacken des Wörterbuchs an. Siehe python.org/dev/peps/pep-0448
devnul3
13

Ich glaube nicht, dass es einen Namen hat. In den Python-Dokumenten unter "Entpacken von Argumentlisten" wird es nur als "der **-Operator" bezeichnet.

Ich bin nicht sicher, was Sie mit "der anderen" Datenstruktur meinen. Wenn Sie dies tun f(**kwargs), entpacken Sie das Wörterbuch kwargsals eine Folge von Schlüssel-Wert-Paaren. Ich sehe nicht, dass es sich um eine andere Struktur handelt.

Ich werde das Beispiel in der obigen Dokumentation zur Verdeutlichung kopieren .

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print "-- This parrot wouldn't", action,
...     print "if you put", voltage, "volts through it.",
...     print "E's", state, "!"
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

Siehe auch: Was bedeuten * args und ** kwargs?

Kris Harper
quelle
Es gibt verschiedene Möglichkeiten, wie ein Leser interpretieren kann f(**kwargs)...
Deer Hunter
3

Wenn Sie sich nicht sicher sind, wie Sie einen bestimmten Operator anrufen sollen, oder wenn er nicht benannt ist, können Sie immer auf Waka Waka Bang Splat als Referenz zurückgreifen , um herauszufinden, wie Sie ihn anrufen sollen. In diesem Fall **würde ich es nennen double-splat, obwohl es einige alternative Namen für Symbole gibt .

aculich
quelle