6. Ausdrücke¶
Dieses Kapitel erklärt die Bedeutung der Elemente von Ausdrücken in Python.
Syntaxhinweise: In diesem und den folgenden Kapiteln wird eine erweiterte BNF-Notation zur Beschreibung der Syntax verwendet, nicht der lexikalischen Analyse. Wenn (eine Alternative von) einer Syntaxregel die Form hat
name: othername
und keine Semantik angegeben ist, sind die Semantik dieser Form von name dieselben wie für othername.
6.1. Arithmetische Konvertierungen¶
Wenn eine Beschreibung eines arithmetischen Operators unten den Ausdruck „die numerischen Argumente werden in einen gemeinsamen reellen Typ konvertiert“ verwendet, bedeutet dies, dass die Implementierung des Operators für eingebaute Typen wie folgt funktioniert:
Wenn beide Argumente komplexe Zahlen sind, wird keine Konvertierung durchgeführt;
Wenn ein Argument eine komplexe Zahl oder eine Fließkommazahl ist, wird das andere in eine Fließkommazahl konvertiert;
andernfalls müssen beide ganze Zahlen sein und es ist keine Konvertierung erforderlich.
Für bestimmte Operatoren gelten zusätzliche Regeln (z. B. ein String als linkes Argument des Operators ‚%‘). Erweiterungen müssen ihr eigenes Konvertierungsverhalten definieren.
6.2. Atome¶
Atome sind die grundlegendsten Elemente von Ausdrücken. Die einfachsten Atome sind Bezeichner oder Literale. Formen, die in Klammern, eckigen Klammern oder geschweiften Klammern eingeschlossen sind, werden ebenfalls syntaktisch als Atome kategorisiert. Die Syntax für Atome lautet
atom:identifier|literal|enclosureenclosure:parenth_form|list_display|dict_display|set_display|generator_expression|yield_atom
6.2.1. Bezeichner (Namen)¶
Ein Bezeichner, der als Atom auftritt, ist ein Name. Siehe Abschnitt Namen (Bezeichner und Schlüsselwörter) für die lexikalische Definition und Abschnitt Benennung und Bindung für die Dokumentation von Benennung und Bindung.
Wenn der Name an ein Objekt gebunden ist, liefert die Auswertung des Atoms dieses Objekt. Wenn ein Name nicht gebunden ist, löst der Versuch, ihn auszuwerten, eine Ausnahme vom Typ NameError aus.
6.2.1.1. Private Name Mangling¶
Wenn ein Bezeichner, der textuell in einer Klassendefinition vorkommt, mit zwei oder mehr Unterstrichen beginnt und nicht mit zwei oder mehr Unterstrichen endet, gilt er als privater Name dieser Klasse.
Siehe auch
Genauer gesagt werden private Namen vor der Codegenerierung in eine längere Form umgewandelt. Wenn der umgewandelte Name länger als 255 Zeichen ist, kann es zu einer implementierungsabhängigen Kürzung kommen.
Die Transformation ist unabhängig vom syntaktischen Kontext, in dem der Bezeichner verwendet wird, aber nur die folgenden privaten Bezeichner werden mangled:
Jeder Name, der als Name einer Variablen verwendet wird, der zugewiesen oder von der gelesen wird, oder jeder Name eines Attributs, auf das zugegriffen wird.
Das Attribut
__name__von verschachtelten Funktionen, Klassen und Typalias wird jedoch nicht mangled.Der Name importierter Module, z. B.
__spaminimport __spam. Wenn das Modul Teil eines Pakets ist (d. h. sein Name enthält einen Punkt), wird der Name *nicht* mangled, z. B. wird das__fooinimport __foo.barnicht mangled.Der Name eines importierten Mitglieds, z. B.
__finfrom spam import __f.
Die Transformationsregel lautet wie folgt:
Der Klassenname, wobei führende Unterstriche entfernt und ein einzelner führender Unterstrich eingefügt wird, wird vor den Bezeichner gesetzt, z. B. der Bezeichner
__spam, der in einer Klasse namensFoo,_Foooder__Foovorkommt, wird zu_Foo__spamtransformiert.Wenn der Klassenname nur aus Unterstrichen besteht, ist die Transformation die Identität, z. B. der Bezeichner
__spam, der in einer Klasse namens_oder__vorkommt, bleibt unverändert.
6.2.2. Literale¶
Python unterstützt String- und Byte-Literale sowie verschiedene numerische Literale:
literal:strings|NUMBER
Die Auswertung eines Literals liefert ein Objekt des angegebenen Typs (String, Bytes, Ganzzahl, Fließkommazahl, komplexe Zahl) mit dem angegebenen Wert. Der Wert kann im Falle von Fließkomma- und imaginären (komplexen) Literalen angenähert sein. Siehe Abschnitt Literale für Details. Siehe Abschnitt Verkettung von String-Literalen für Details zu strings.
Alle Literale entsprechen unveränderlichen Datentypen, und daher ist die Identität des Objekts weniger wichtig als sein Wert. Mehrere Auswertungen von Literalen mit demselben Wert (entweder dasselbe Vorkommen im Programmtext oder ein anderes Vorkommen) können dasselbe Objekt oder ein anderes Objekt mit demselben Wert ergeben.
6.2.2.1. Verkettung von String-Literalen¶
Mehrere aufeinanderfolgende String- oder Byte-Literale (durch Leerzeichen getrennt), die möglicherweise unterschiedliche Anführungszeichenkonventionen verwenden, sind zulässig, und ihre Bedeutung ist dieselbe wie ihre Verkettung:
>>> "hello" 'world'
"helloworld"
Formell:
strings: ( STRING | fstring)+ | tstring+
Dieses Feature ist auf syntaktischer Ebene definiert, daher funktioniert es nur mit Literalen. Um String-Ausdrücke zur Laufzeit zu verketten, kann der ‚+‘-Operator verwendet werden.
>>> greeting = "Hello"
>>> space = " "
>>> name = "Blaise"
>>> print(greeting + space + name) # not: print(greeting space name)
Hello Blaise
Literalverkettung kann rohe Strings, dreifach Anführungszeichen-Strings und formatierte String-Literale frei mischen. Zum Beispiel:
>>> "Hello" r', ' f"{name}!"
"Hello, Blaise!"
Dieses Feature kann verwendet werden, um die Anzahl der benötigten Backslashes zu reduzieren, lange Strings bequem über Zeilen hinweg zu teilen oder sogar Kommentare zu Teilen von Strings hinzuzufügen. Zum Beispiel:
re.compile("[A-Za-z_]" # letter or underscore
"[A-Za-z0-9_]*" # letter, digit or underscore
)
Byte-Literale dürfen jedoch nur mit anderen Byte-Literalen kombiniert werden; nicht mit String-Literalen jeglicher Art. Auch Template-String-Literale dürfen nur mit anderen Template-String-Literalen kombiniert werden.
>>> t"Hello" t"{name}!"
Template(strings=('Hello', '!'), interpolations=(...))
6.2.3. Klammerausdrücke¶
Eine Klammerform ist eine optionale Ausdrucksliste, die in Klammern eingeschlossen ist:
parenth_form: "(" [starred_expression] ")"
Eine geklammerte Ausdrucksliste liefert, was auch immer diese Ausdrucksliste liefert: Wenn die Liste mindestens ein Komma enthält, liefert sie ein Tupel; andernfalls liefert sie den einzelnen Ausdruck, aus dem die Ausdrucksliste besteht.
Ein leeres Klammerpaar liefert ein leeres Tupelobjekt. Da Tupel unveränderlich sind, gelten dieselben Regeln wie für Literale (d. h. zwei Vorkommen des leeren Tupels ergeben möglicherweise dasselbe oder ein anderes Objekt).
Beachten Sie, dass Tupel nicht durch die Klammern gebildet werden, sondern durch die Verwendung des Kommas. Die Ausnahme ist das leere Tupel, für das Klammern *erforderlich* sind – die Zulassung von nicht geklammertem „Nichts“ in Ausdrücken würde zu Mehrdeutigkeiten führen und häufige Tippfehler unbemerkt lassen.
6.2.4. Displays für Listen, Mengen und Wörterbücher¶
Zur Konstruktion einer Liste, einer Menge oder eines Wörterbuchs bietet Python spezielle Syntaxen, sogenannte „Displays“, jeweils in zwei Varianten:
entweder die Containerinhalte sind explizit aufgeführt, oder
sie werden über eine Reihe von Schleifen- und Filteranweisungen berechnet, die als Comprehension bezeichnet werden.
Gängige Syntaxelemente für Comprehensions sind:
comprehension:assignment_expressioncomp_forcomp_for: ["async"] "for"target_list"in"or_test[comp_iter] comp_iter:comp_for|comp_ifcomp_if: "if"or_test[comp_iter]
Die Comprehension besteht aus einem einzelnen Ausdruck, gefolgt von mindestens einer for-Klausel und null oder mehr for- oder if-Klauseln. In diesem Fall sind die Elemente des neuen Containers diejenigen, die durch die Betrachtung jeder der for- oder if-Klauseln als Block, verschachtelt von links nach rechts, erzeugt würden, und die Auswertung des Ausdrucks, um jedes Mal, wenn der innerste Block erreicht wird, ein Element zu produzieren.
Abgesehen vom iterierbaren Ausdruck in der linken for-Klausel wird die Comprehension jedoch in einem separaten, implizit verschachtelten Gültigkeitsbereich ausgeführt. Dies stellt sicher, dass Namen, denen im Ziel eine Zuweisung erfolgt, nicht in den umschließenden Gültigkeitsbereich „auslaufen“.
Der iterierbare Ausdruck in der linken for-Klausel wird direkt im umschließenden Gültigkeitsbereich ausgewertet und dann als Argument an den implizit verschachtelten Gültigkeitsbereich übergeben. Nachfolgende for-Klauseln und jede Filterbedingung in der linken for-Klausel können nicht im umschließenden Gültigkeitsbereich ausgewertet werden, da sie von den Werten abhängen können, die aus dem linken iterierbaren Objekt stammen. Zum Beispiel: [x*y for x in range(10) for y in range(x, x+10)].
Um sicherzustellen, dass die Comprehension immer zu einem Container des entsprechenden Typs führt, sind yield und yield from-Ausdrücke im implizit verschachtelten Gültigkeitsbereich verboten.
Seit Python 3.6 kann in einer async def-Funktion eine async for-Klausel verwendet werden, um über einen asynchronen Iterator zu iterieren. Eine Comprehension in einer async def-Funktion kann entweder eine for- oder async for-Klausel nach dem führenden Ausdruck enthalten, weitere for- oder async for-Klauseln enthalten und auch await-Ausdrücke verwenden.
Wenn eine Comprehension async for-Klauseln enthält oder wenn sie await-Ausdrücke oder andere asynchrone Comprehensions enthält, außer im iterierbaren Ausdruck in der linken for-Klausel, wird sie als asynchrone Comprehension bezeichnet. Eine asynchrone Comprehension kann die Ausführung der Coroutine-Funktion, in der sie erscheint, unterbrechen. Siehe auch PEP 530.
Hinzugefügt in Version 3.6: Asynchrone Comprehensions wurden eingeführt.
Geändert in Version 3.8: yield und yield from sind im implizit verschachtelten Gültigkeitsbereich verboten.
Geändert in Version 3.11: Asynchrone Comprehensions sind jetzt innerhalb von Comprehensions in asynchronen Funktionen erlaubt. Äußere Comprehensions werden implizit asynchron.
6.2.5. Listen-Displays¶
Ein Listen-Display ist eine möglicherweise leere Reihe von Ausdrücken, die in eckige Klammern eingeschlossen sind:
list_display: "[" [flexible_expression_list|comprehension] "]"
Ein Listen-Display liefert ein neues Listenobjekt, dessen Inhalt entweder durch eine Liste von Ausdrücken oder durch eine Comprehension bestimmt wird. Wenn eine kommaseparierte Liste von Ausdrücken angegeben wird, werden ihre Elemente von links nach rechts ausgewertet und in dieser Reihenfolge in das Listenobjekt eingefügt. Wenn eine Comprehension angegeben wird, wird die Liste aus den von der Comprehension erzeugten Elementen aufgebaut.
6.2.6. Mengen-Displays¶
Ein Mengen-Display wird durch geschweifte Klammern gekennzeichnet und unterscheidet sich von Dictionary-Displays durch das Fehlen von Doppelpunkten, die Schlüssel und Werte trennen:
set_display: "{" (flexible_expression_list|comprehension) "}"
Ein Mengen-Display liefert ein neues veränderliches Mengenobjekt, dessen Inhalt entweder durch eine Sequenz von Ausdrücken oder durch eine Comprehension bestimmt wird. Wenn eine kommaseparierte Liste von Ausdrücken angegeben wird, werden ihre Elemente von links nach rechts ausgewertet und dem Mengenobjekt hinzugefügt. Wenn eine Comprehension angegeben wird, wird die Menge aus den von der Comprehension erzeugten Elementen aufgebaut.
Eine leere Menge kann nicht mit {} konstruiert werden; dieses Literal konstruiert ein leeres Wörterbuch.
6.2.7. Dictionary-Displays¶
Ein Dictionary-Display ist eine möglicherweise leere Reihe von Dictionary-Elementen (Schlüssel/Wert-Paaren), die in geschweifte Klammern eingeschlossen sind:
dict_display: "{" [dict_item_list|dict_comprehension] "}" dict_item_list:dict_item(","dict_item)* [","] dict_item:expression":"expression| "**"or_exprdict_comprehension:expression":"expressioncomp_for
Ein Dictionary-Display liefert ein neues Dictionary-Objekt.
Wenn eine kommaseparierte Sequenz von Dictionary-Elementen angegeben wird, werden diese von links nach rechts ausgewertet, um die Einträge des Wörterbuchs zu definieren: Jedes Schlüsselobjekt wird als Schlüssel in das Wörterbuch verwendet, um den entsprechenden Wert zu speichern. Das bedeutet, dass Sie denselben Schlüssel mehrmals in der Liste der Dictionary-Elemente angeben können, und der endgültige Wert des Wörterbuchs für diesen Schlüssel ist der zuletzt angegebene.
Ein doppeltes Sternchen ** bezeichnet Dictionary Unpacking. Sein Operand muss eine Mapping sein. Jedes Mapping-Element wird dem neuen Wörterbuch hinzugefügt. Spätere Werte ersetzen Werte, die bereits von früheren Dictionary-Elementen und früheren Dictionary-Unpackings gesetzt wurden.
Hinzugefügt in Version 3.5: Unpacking in Dictionary-Displays, ursprünglich vorgeschlagen von PEP 448.
Eine Dict-Comprehension benötigt im Gegensatz zu Listen- und Mengen-Comprehensions zwei mit einem Doppelpunkt getrennte Ausdrücke, gefolgt von den üblichen „for“- und „if“-Klauseln. Wenn die Comprehension ausgeführt wird, werden die resultierenden Schlüssel- und Wertelemente in der Reihenfolge, in der sie erzeugt werden, in das neue Wörterbuch eingefügt.
Beschränkungen für die Typen der Schlüsselwerte sind weiter oben in Abschnitt Die Standard-Typhierarchie aufgeführt. (Zusammenfassend sollte der Schlüsseltyp hashable sein, was alle veränderlichen Objekte ausschließt.) Konflikte zwischen doppelten Schlüsseln werden nicht erkannt; der letzte für einen gegebenen Schlüsselwert gespeicherte Wert (textuell rechts im Display) hat Vorrang.
Geändert in Version 3.8: Vor Python 3.8 war die Auswertungsreihenfolge von Schlüssel und Wert in Dict-Comprehensions nicht gut definiert. In CPython wurde der Wert vor dem Schlüssel ausgewertet. Ab 3.8 wird der Schlüssel vor dem Wert ausgewertet, wie von PEP 572 vorgeschlagen.
6.2.8. Generator-Ausdrücke¶
Ein Generator-Ausdruck ist eine kompakte Generator-Notation in Klammern:
generator_expression: "("expressioncomp_for")"
Ein Generator-Ausdruck liefert ein neues Generatorobjekt. Seine Syntax ist dieselbe wie bei Comprehensions, nur dass er anstelle von eckigen oder geschweiften Klammern in runde Klammern eingeschlossen ist.
Variablen, die im Generator-Ausdruck verwendet werden, werden träge ausgewertet, wenn die Methode __next__() für das Generatorobjekt aufgerufen wird (auf die gleiche Weise wie bei normalen Generatoren). Der iterierbare Ausdruck in der linken for-Klausel wird jedoch sofort ausgewertet und der Iterator für dieses Iterable wird sofort erstellt, sodass ein Fehler, der beim Erstellen des Iterators auftritt, an der Stelle ausgegeben wird, an der der Generator-Ausdruck definiert wird, anstatt an der Stelle, an der der erste Wert abgerufen wird. Nachfolgende for-Klauseln und jede Filterbedingung in der linken for-Klausel können nicht im umschließenden Gültigkeitsbereich ausgewertet werden, da sie von den Werten abhängen können, die aus dem linken iterierbaren Objekt stammen. Zum Beispiel: (x*y for x in range(10) for y in range(x, x+10)).
Die Klammern können bei Aufrufen mit nur einem Argument weggelassen werden. Siehe Abschnitt Aufrufe für Details.
Um die erwartete Funktionsweise des Generator-Ausdrucks selbst nicht zu beeinträchtigen, sind yield- und yield from-Ausdrücke im implizit definierten Generator verboten.
Wenn ein Generator-Ausdruck entweder async for-Klauseln oder await-Ausdrücke enthält, wird er als asynchroner Generator-Ausdruck bezeichnet. Ein asynchroner Generator-Ausdruck gibt ein neues asynchrones Generatorobjekt zurück, das ein asynchroner Iterator ist (siehe Asynchrone Iteratoren).
Hinzugefügt in Version 3.6: Asynchrone Generator-Ausdrücke wurden eingeführt.
Geändert in Version 3.7: Vor Python 3.7 konnten asynchrone Generator-Ausdrücke nur in async def-Coroutinen vorkommen. Ab 3.7 können beliebige Funktionen asynchrone Generator-Ausdrücke verwenden.
Geändert in Version 3.8: yield und yield from sind im implizit verschachtelten Gültigkeitsbereich verboten.
6.2.9. Yield-Ausdrücke¶
yield_atom: "("yield_expression")" yield_from: "yield" "from"expressionyield_expression: "yield"yield_list|yield_from
Der Yield-Ausdruck wird bei der Definition einer Generatorfunktion oder einer asynchronen Generatorfunktion verwendet und kann daher nur im Körper einer Funktionsdefinition verwendet werden. Die Verwendung eines Yield-Ausdrucks im Körper einer Funktion macht diese Funktion zu einer Generatorfunktion, und die Verwendung im Körper einer async def-Funktion macht diese Coroutine-Funktion zu einer asynchronen Generatorfunktion. Zum Beispiel:
def gen(): # defines a generator function
yield 123
async def agen(): # defines an asynchronous generator function
yield 123
Aufgrund ihrer Seiteneffekte auf den enthaltenden Gültigkeitsbereich sind yield-Ausdrücke nicht erlaubt als Teil der implizit definierten Gültigkeitsbereiche, die zur Implementierung von Comprehensions und Generator-Ausdrücken verwendet werden.
Geändert in Version 3.8: Yield-Ausdrücke sind in den implizit verschachtelten Gültigkeitsbereichen, die zur Implementierung von Comprehensions und Generator-Ausdrücken verwendet werden, verboten.
Generatorfunktionen werden unten beschrieben, während asynchrone Generatorfunktionen separat in Abschnitt Asynchrone Generatorfunktionen beschrieben werden.
Wenn eine Generatorfunktion aufgerufen wird, gibt sie einen Iterator zurück, der als Generator bekannt ist. Dieser Generator steuert dann die Ausführung der Generatorfunktion. Die Ausführung beginnt, wenn eine der Methoden des Generators aufgerufen wird. Zu diesem Zeitpunkt geht die Ausführung zum ersten Yield-Ausdruck, wo sie erneut angehalten wird und den Wert von yield_list an den Aufrufer des Generators zurückgibt oder None, wenn yield_list weggelassen wird. Mit „angehalten“ meinen wir, dass der gesamte lokale Zustand beibehalten wird, einschließlich der aktuellen Bindungen lokaler Variablen, des Instruktionszeigers, des internen Auswertungsstapels und des Zustands jeglicher Ausnahmebehandlung. Wenn die Ausführung durch den Aufruf einer der Methoden des Generators fortgesetzt wird, kann die Funktion genau so fortfahren, als wäre der Yield-Ausdruck nur ein weiterer externer Aufruf. Der Wert des Yield-Ausdrucks nach der Fortsetzung hängt von der Methode ab, die die Ausführung fortgesetzt hat. Wenn __next__() verwendet wird (typischerweise entweder über eine for-Schleife oder die eingebaute Funktion next()), dann ist das Ergebnis None. Andernfalls, wenn send() verwendet wird, ist das Ergebnis der Wert, der an diese Methode übergeben wurde.
All dies macht Generatorfunktionen ziemlich ähnlich zu Coroutinen; sie geben mehrmals Werte zurück, sie haben mehr als einen Einstiegspunkt und ihre Ausführung kann angehalten werden. Der einzige Unterschied besteht darin, dass eine Generatorfunktion nicht steuern kann, wo die Ausführung nach dem Yield fortgesetzt werden soll; die Kontrolle wird immer an den Aufrufer des Generators übertragen.
Yield-Ausdrücke sind überall in einem try-Konstrukt erlaubt. Wenn der Generator nicht wieder aufgenommen wird, bevor er abgeschlossen ist (durch Erreichen eines Referenzzählers von Null oder durch Garbage Collection), wird die Methode close() des Generator-Iterators aufgerufen, was die Ausführung aller ausstehenden finally-Klauseln ermöglicht.
Wenn yield from <expr> verwendet wird, muss der angegebene Ausdruck ein Iterable sein. Die von der Iteration dieses Iterables erzeugten Werte werden direkt an den Aufrufer der Methoden des aktuellen Generators weitergeleitet. Alle Werte, die mit send() übergeben und alle Ausnahmen, die mit throw() übergeben werden, werden an den zugrunde liegenden Iterator weitergeleitet, wenn dieser die entsprechenden Methoden hat. Wenn dies nicht der Fall ist, löst send() eine AttributeError oder eine TypeError aus, während throw() einfach die übergebene Ausnahme sofort auslöst.
Wenn der zugrunde liegende Iterator abgeschlossen ist, wird das Attribut value der ausgelösten StopIteration-Instanz zum Wert des Yield-Ausdrucks. Es kann entweder explizit beim Auslösen von StopIteration gesetzt werden oder automatisch, wenn der Sub-Iterator ein Generator ist (durch Rückgabe eines Wertes aus dem Sub-Generator).
Geändert in Version 3.3: yield from <expr> wurde hinzugefügt, um den Kontrollfluss an einen Sub-Iterator zu delegieren.
Die Klammern können weggelassen werden, wenn der Yield-Ausdruck der einzige Ausdruck auf der rechten Seite einer Zuweisungsanweisung ist.
Siehe auch
- PEP 255 - Einfache Generatoren
Der Vorschlag zur Ergänzung von Generatoren und der
yield-Anweisung in Python.- PEP 342 - Coroutinen durch erweiterte Generatoren
Der Vorschlag zur Erweiterung der API und Syntax von Generatoren, um sie als einfache Coroutinen nutzbar zu machen.
- PEP 380 - Syntax zur Delegation an einen Sub-Generator
Der Vorschlag zur Einführung der
yield_from-Syntax, die die Delegation an Sub-Generatoren vereinfacht.- PEP 525 - Asynchrone Generatoren
Der Vorschlag, der auf PEP 492 aufbaut, indem er Coroutine-Funktionen Generatorfähigkeiten hinzufügt.
6.2.9.1. Generator-Iterator-Methoden¶
Dieser Unterabschnitt beschreibt die Methoden eines Generator-Iterators. Sie können verwendet werden, um die Ausführung einer Generatorfunktion zu steuern.
Beachten Sie, dass der Aufruf einer der unten aufgeführten Generatormethoden, während der Generator bereits ausgeführt wird, eine Ausnahme vom Typ ValueError auslöst.
- generator.__next__()¶
Startet die Ausführung einer Generatorfunktion oder setzt sie am zuletzt ausgeführten Yield-Ausdruck fort. Wenn eine Generatorfunktion mit der Methode
__next__()wieder aufgenommen wird, wird der aktuelle Yield-Ausdruck immer zuNoneausgewertet. Die Ausführung wird dann zum nächsten Yield-Ausdruck fortgesetzt, wo der Generator erneut angehalten wird und der Wert deryield_listan den Aufrufer von__next__()zurückgegeben wird. Wenn der Generator ohne Rückgabe eines weiteren Werts beendet wird, wird eine Ausnahme vom TypStopIterationausgelöst.Diese Methode wird normalerweise implizit aufgerufen, z. B. von einer
for-Schleife oder von der eingebauten Funktionnext().
- generator.send(value)¶
Setzt die Ausführung fort und „sendet“ einen Wert in die Generatorfunktion. Das Argument value wird zum Ergebnis des aktuellen Yield-Ausdrucks. Die Methode
send()gibt den nächsten vom Generator gelieferten Wert zurück oder löstStopIterationaus, wenn der Generator beendet wird, ohne einen weiteren Wert zu liefern. Wennsend()aufgerufen wird, um den Generator zu starten, muss er mitNoneals Argument aufgerufen werden, da kein Yield-Ausdruck existiert, der den Wert empfangen könnte.
- generator.throw(value)¶
- generator.throw(typ[, val[, tb]])
Löst eine Ausnahme an der Stelle aus, an der der Generator pausiert wurde, und gibt den nächsten von der Generatorfunktion erzeugten Wert zurück. Wenn die Generatorfunktion endet, ohne einen weiteren Wert zu erzeugen, wird eine
StopIteration-Ausnahme ausgelöst. Wenn die Generatorfunktion die übergebene Ausnahme nicht abfängt oder eine andere Ausnahme auslöst, breitet sich diese Ausnahme auf den Aufrufer aus.In der typischen Verwendung wird dies mit einer einzelnen Ausnahminstanz aufgerufen, ähnlich wie das Schlüsselwort
raiseverwendet wird.Aus Kompatibilitätsgründen wird jedoch die zweite Signatur unterstützt, die einer Konvention älterer Python-Versionen folgt. Das Argument typ sollte eine Ausnahmeklasse sein und val eine Ausnahminstanz. Wenn val nicht bereitgestellt wird, wird der typ-Konstruktor aufgerufen, um eine Instanz zu erhalten. Wenn tb bereitgestellt wird, wird es der Ausnahme zugewiesen, andernfalls kann jedes vorhandene
__traceback__-Attribut, das in val gespeichert ist, gelöscht werden.Geändert in Version 3.12: Die zweite Signatur (typ[, val[, tb]]) ist veraltet und könnte in einer zukünftigen Python-Version entfernt werden.
- generator.close()¶
Löst eine
GeneratorExit-Ausnahme an der Stelle aus, an der die Generatorfunktion pausiert wurde (entspricht dem Aufruf vonthrow(GeneratorExit)). Die Ausnahme wird vom Yield-Ausdruck ausgelöst, bei dem der Generator pausiert wurde. Wenn die Generatorfunktion die Ausnahme abfängt und einen Wert zurückgibt, wird dieser Wert vonclose()zurückgegeben. Wenn die Generatorfunktion bereits geschlossen ist oderGeneratorExitauslöst (indem sie die Ausnahme nicht abfängt), gibtclose()Nonezurück. Wenn der Generator einen Wert erzeugt, wird eineRuntimeErrorausgelöst. Wenn der Generator eine andere Ausnahme auslöst, wird diese an den Aufrufer weitergegeben. Wenn der Generator bereits aufgrund einer Ausnahme oder eines normalen Beendigens beendet wurde, gibtclose()Nonezurück und hat keine weitere Auswirkung.Geändert in Version 3.13: Wenn ein Generator beim Schließen einen Wert zurückgibt, wird der Wert von
close()zurückgegeben.
6.2.9.2. Beispiele¶
Hier ist ein einfaches Beispiel, das das Verhalten von Generatoren und Generatorfunktionen demonstriert
>>> def echo(value=None):
... print("Execution starts when 'next()' is called for the first time.")
... try:
... while True:
... try:
... value = (yield value)
... except Exception as e:
... value = e
... finally:
... print("Don't forget to clean up when 'close()' is called.")
...
>>> generator = echo(1)
>>> print(next(generator))
Execution starts when 'next()' is called for the first time.
1
>>> print(next(generator))
None
>>> print(generator.send(2))
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Don't forget to clean up when 'close()' is called.
Beispiele für die Verwendung von yield from finden Sie in PEP 380: Syntax for Delegating to a Subgenerator in „What’s New in Python.“
6.2.9.3. Asynchrone Generatorfunktionen¶
Das Vorhandensein eines `yield`-Ausdrucks in einer Funktion oder Methode, die mit async def definiert wurde, definiert die Funktion weiter als asynchrone Generatorfunktion.
Wenn eine asynchrone Generatorfunktion aufgerufen wird, gibt sie einen asynchronen Iterator zurück, der als asynchrones Generatorobjekt bekannt ist. Dieses Objekt steuert dann die Ausführung der Generatorfunktion. Ein asynchrones Generatorobjekt wird typischerweise in einer async for-Anweisung in einer Coroutine-Funktion analog zur Verwendung eines Generatorobjekts in einer for-Anweisung verwendet.
Der Aufruf einer der Methoden des asynchronen Generators gibt ein awaitable-Objekt zurück, und die Ausführung beginnt, wenn dieses Objekt awaited wird. Zu diesem Zeitpunkt schreitet die Ausführung bis zum ersten `yield`-Ausdruck fort, wo sie wieder unterbrochen wird und der Wert von yield_list an die wartende Coroutine zurückgegeben wird. Wie bei einem Generator bedeutet die Unterbrechung, dass der gesamte lokale Zustand beibehalten wird, einschließlich der aktuellen Bindungen lokaler Variablen, des Instruktionszeigers, des internen Auswertungsstapels und des Zustands jeglicher Ausnahmebehandlung. Wenn die Ausführung durch das Warten auf das nächste von den Methoden des asynchronen Generators zurückgegebene Objekt fortgesetzt wird, kann die Funktion genau so fortfahren, als wäre der `yield`-Ausdruck nur ein weiterer externer Aufruf. Der Wert des `yield`-Ausdrucks nach der Fortsetzung hängt von der Methode ab, die die Ausführung fortgesetzt hat. Wenn __anext__() verwendet wird, ist das Ergebnis None. Andernfalls, wenn asend() verwendet wird, ist das Ergebnis der Wert, der an diese Methode übergeben wurde.
Wenn ein asynchroner Generator durch break, die Abbrechung der aufrufenden Aufgabe oder andere Ausnahmen vorzeitig beendet wird, wird der asynchrone Cleanup-Code des Generators ausgeführt und möglicherweise Ausnahmen ausgelöst oder Kontextvariablen in einem unerwarteten Kontext zugegriffen – vielleicht nach der Lebensdauer der Aufgaben, von denen er abhängt, oder während des Herunterfahrens der Ereignisschleife, wenn der Garbage-Collection-Hook für asynchrone Generatoren aufgerufen wird. Um dies zu verhindern, muss der Aufrufer den asynchronen Generator explizit schließen, indem er die Methode aclose() aufruft, um den Generator zu finalisieren und ihn schließlich von der Ereignisschleife zu trennen.
In einer asynchronen Generatorfunktion sind `yield`-Ausdrücke überall in einer try-Konstruktion zulässig. Wenn ein asynchroner Generator jedoch nicht fortgesetzt wird, bevor er finalisiert wird (durch Erreichen einer Referenzanzahl von Null oder durch Garbage-Collection), kann ein `yield`-Ausdruck innerhalb einer try-Konstruktion dazu führen, dass ausstehende finally-Klauseln nicht ausgeführt werden. In diesem Fall liegt es in der Verantwortung der Ereignisschleife oder des Schedulers, der den asynchronen Generator ausführt, die Methode aclose() des asynchronen Generator-Iterators aufzurufen und das resultierende Coroutine-Objekt auszuführen, wodurch alle ausstehenden finally-Klauseln ausgeführt werden können.
Um die Finalisierung bei Beendigung der Ereignisschleife zu übernehmen, sollte eine Ereignisschleife eine Finalizerfunktion definieren, die einen asynchronen Generator-Iterator übernimmt und vermutlich aclose() aufruft und die Coroutine ausführt. Dieser Finalizer kann durch Aufruf von sys.set_asyncgen_hooks() registriert werden. Bei der ersten Iteration speichert ein asynchroner Generator-Iterator den registrierten Finalizer, der bei der Finalisierung aufgerufen wird. Als Referenzbeispiel für eine Finalizer-Methode siehe die Implementierung von asyncio.Loop.shutdown_asyncgens in Lib/asyncio/base_events.py.
Der Ausdruck yield from <expr> ist ein Syntaxfehler, wenn er in einer asynchronen Generatorfunktion verwendet wird.
6.2.9.4. Methoden von asynchronen Generator-Iteratoren¶
Dieser Unterabschnitt beschreibt die Methoden eines asynchronen Generator-Iterators, die zur Steuerung der Ausführung einer Generatorfunktion verwendet werden.
- async agen.__anext__()¶
Gibt ein `awaitable` zurück, das beim Ausführen beginnt, den asynchronen Generator auszuführen oder ihn an der zuletzt ausgeführten `yield`-Ausdruck fortzusetzen. Wenn eine asynchrone Generatorfunktion mit einer
__anext__()-Methode fortgesetzt wird, wird der aktuelle `yield`-Ausdruck immer zuNoneim zurückgegebenen `awaitable` ausgewertet, das beim Ausführen zum nächsten `yield`-Ausdruck fortfährt. Der Wert deryield_listdes `yield`-Ausdrucks ist der Wert derStopIteration-Ausnahme, die von der abschließenden Coroutine ausgelöst wird. Wenn der asynchrone Generator endet, ohne einen weiteren Wert zu erzeugen, löst das `awaitable` stattdessen eineStopAsyncIteration-Ausnahme aus, die signalisiert, dass die asynchrone Iteration abgeschlossen ist.Diese Methode wird normalerweise implizit von einer
async for-Schleife aufgerufen.
- async agen.asend(val)¶
Gibt ein `awaitable` zurück, das beim Ausführen die Ausführung des asynchronen Generators fortsetzt. Wie bei der
send()-Methode für einen Generator „sendet“ diese Methode einen Wert in die asynchrone Generatorfunktion, und das Argument val wird zum Ergebnis des aktuellen `yield`-Ausdrucks. Das von derasend()-Methode zurückgegebene `awaitable` gibt den nächsten von der Generatorfunktion erzeugten Wert als Wert der ausgelöstenStopIteration-Ausnahme zurück oder löstStopAsyncIterationaus, wenn der asynchrone Generator endet, ohne einen weiteren Wert zu erzeugen. Wennasend()zum Starten des asynchronen Generators aufgerufen wird, muss es mitNoneals Argument aufgerufen werden, da kein `yield`-Ausdruck vorhanden ist, der den Wert empfangen könnte.
- async agen.athrow(val)¶
- async agen.athrow(typ[, val[, tb]])
Gibt ein `awaitable` zurück, das eine Ausnahme vom Typ
typan der Stelle auslöst, an der der asynchrone Generator pausiert wurde, und den nächsten von der Generatorfunktion erzeugten Wert als Wert der ausgelöstenStopIteration-Ausnahme zurückgibt. Wenn der asynchrone Generator endet, ohne einen weiteren Wert zu erzeugen, wird eineStopAsyncIteration-Ausnahme vom `awaitable` ausgelöst. Wenn die Generatorfunktion die übergebene Ausnahme nicht abfängt oder eine andere Ausnahme auslöst, breitet sich diese Ausnahme beim Ausführen des `awaitable` auf den Aufrufer des `awaitable` aus.Geändert in Version 3.12: Die zweite Signatur (typ[, val[, tb]]) ist veraltet und könnte in einer zukünftigen Python-Version entfernt werden.
- async agen.aclose()¶
Gibt ein `awaitable` zurück, das beim Ausführen eine
GeneratorExitin die asynchrone Generatorfunktion an der Stelle wirft, an der sie pausiert wurde. Wenn die asynchrone Generatorfunktion dann ordnungsgemäß beendet wird, bereits geschlossen ist oderGeneratorExitauslöst (indem sie die Ausnahme nicht abfängt), löst das zurückgegebene `awaitable` eineStopIteration-Ausnahme aus. Alle weiteren `awaitable`s, die von nachfolgenden Aufrufen des asynchronen Generators zurückgegeben werden, lösen eineStopAsyncIteration-Ausnahme aus. Wenn der asynchrone Generator einen Wert erzeugt, löst das `awaitable` eineRuntimeErroraus. Wenn der asynchrone Generator eine andere Ausnahme auslöst, wird diese an den Aufrufer des `awaitable` weitergegeben. Wenn der asynchrone Generator bereits aufgrund einer Ausnahme oder einer normalen Beendigung beendet wurde, lösen nachfolgende Aufrufe vonaclose()ein `awaitable` zurück, das nichts tut.
6.3. Primäre Ausdrücke¶
Primäre Ausdrücke repräsentieren die am engsten gebundenen Operationen der Sprache. Ihre Syntax ist:
primary:atom|attributeref|subscription|slicing|call
6.3.1. Attributreferenzen¶
Eine Attributreferenz ist ein primärer Ausdruck gefolgt von einem Punkt und einem Namen.
attributeref:primary"."identifier
Der primäre Ausdruck muss zu einem Objekt eines Typs ausgewertet werden, der Attributreferenzen unterstützt, was für die meisten Objekte der Fall ist. Dieses Objekt wird dann aufgefordert, das Attribut bereitzustellen, dessen Name der Bezeichner ist. Der Typ und der erzeugte Wert werden vom Objekt bestimmt. Mehrere Auswertungen derselben Attributreferenz können unterschiedliche Objekte ergeben.
Diese Produktion kann durch Überschreiben der Methode __getattribute__() oder der Methode __getattr__() angepasst werden. Die Methode __getattribute__() wird zuerst aufgerufen und gibt entweder einen Wert zurück oder löst AttributeError aus, wenn das Attribut nicht verfügbar ist.
Wenn ein AttributeError ausgelöst wird und das Objekt eine __getattr__()-Methode hat, wird diese Methode als Fallback aufgerufen.
6.3.2. Abonnements¶
Das Abonnement einer Instanz einer Containerklasse wählt im Allgemeinen ein Element aus dem Container aus. Das Abonnement einer generischen Klasse gibt im Allgemeinen ein GenericAlias-Objekt zurück.
subscription:primary"["flexible_expression_list"]"
Wenn ein Objekt abonniert wird, wertet der Interpreter den primären Ausdruck und die Ausdrucksliste aus.
Der primäre Ausdruck muss zu einem Objekt ausgewertet werden, das ein Abonnement unterstützt. Ein Objekt kann ein Abonnement unterstützen, indem es eine oder beide der Methoden __getitem__() und __class_getitem__() definiert. Wenn der primäre Ausdruck abonniert wird, wird das ausgewertete Ergebnis der Ausdrucksliste an eine dieser Methoden übergeben. Weitere Details dazu, wann __class_getitem__ anstelle von __getitem__ aufgerufen wird, finden Sie unter __class_getitem__ versus __getitem__.
Wenn die Ausdrucksliste mindestens ein Komma enthält oder wenn einer der Ausdrücke mit einem Sternchen versehen ist, wird die Ausdrucksliste zu einem tuple ausgewertet, das die Elemente der Ausdrucksliste enthält. Andernfalls wird die Ausdrucksliste zum Wert des einzigen Elements der Liste ausgewertet.
Geändert in Version 3.11: Ausdrücke in einer Ausdrucksliste können mit einem Sternchen versehen sein. Siehe PEP 646.
Für eingebaute Objekte gibt es zwei Arten von Objekten, die ein Abonnement über __getitem__() unterstützen:
Mappings. Wenn der primäre Ausdruck ein Mapping ist, muss die Ausdrucksliste zu einem Objekt ausgewertet werden, dessen Wert einer der Schlüssel des Mappings ist, und das Abonnement wählt den Wert im Mapping aus, der diesem Schlüssel entspricht. Ein Beispiel für eine eingebaute Mapping-Klasse ist die
dict-Klasse.Sequenzen. Wenn der primäre Ausdruck eine Sequenz ist, muss die Ausdrucksliste zu einer
intoder einemslice(wie im folgenden Abschnitt besprochen) ausgewertet werden. Beispiele für eingebaute Sequenzklassen sind die Klassenstr,listundtuple.
Die formale Syntax sieht keine besonderen Vorkehrungen für negative Indizes in Sequenzen vor. Eingebaute Sequenzen bieten jedoch alle eine __getitem__()-Methode, die negative Indizes interpretiert, indem sie die Länge der Sequenz zum Index addiert, sodass beispielsweise x[-1] das letzte Element von x auswählt. Der resultierende Wert muss eine nichtnegative ganze Zahl kleiner als die Anzahl der Elemente in der Sequenz sein, und das Abonnement wählt das Element aus, dessen Index dieser Wert ist (gezählt ab Null). Da die Unterstützung für negative Indizes und Slicing in der __getitem__()-Methode des Objekts stattfindet, müssen Unterklassen, die diese Methode überschreiben, diese Unterstützung explizit hinzufügen.
Ein String ist eine spezielle Art von Sequenz, deren Elemente *Zeichen* sind. Ein Zeichen ist kein separater Datentyp, sondern ein String von genau einem Zeichen.
6.3.3. Slicings¶
Ein Slicing wählt einen Bereich von Elementen in einem Sequenzobjekt (z. B. einem String, Tupel oder einer Liste) aus. Slicings können als Ausdrücke oder als Ziele in Zuweisungs- oder del-Anweisungen verwendet werden. Die Syntax für ein Slicing:
slicing:primary"["slice_list"]" slice_list:slice_item(","slice_item)* [","] slice_item:expression|proper_sliceproper_slice: [lower_bound] ":" [upper_bound] [ ":" [stride] ] lower_bound:expressionupper_bound:expressionstride:expression
Es gibt eine Mehrdeutigkeit in der formalen Syntax: Alles, was wie eine Ausdrucksliste aussieht, sieht auch wie eine Slice-Liste aus, sodass jedes Abonnement als Slicing interpretiert werden kann. Anstatt die Syntax weiter zu verkomplizieren, wird dies dadurch disambiguiert, dass die Interpretation als Abonnement Vorrang vor der Interpretation als Slicing hat (dies ist der Fall, wenn die Slice-Liste keinen echten Slice enthält).
Die Semantik für ein Slicing ist wie folgt. Der primäre Ausdruck wird (mit derselben __getitem__()-Methode wie normale Abonnements) mit einem Schlüssel indiziert, der aus der Slice-Liste konstruiert wird, wie folgt. Wenn die Slice-Liste mindestens ein Komma enthält, ist der Schlüssel ein Tupel, das die Konvertierung der Slice-Elemente enthält; andernfalls ist die Konvertierung des einzigen Slice-Elements der Schlüssel. Die Konvertierung eines Slice-Elements, das ein Ausdruck ist, ist dieser Ausdruck. Die Konvertierung eines echten Slices ist ein Slice-Objekt (siehe Abschnitt Die Standard-Typhierarchie), dessen Attribute start, stop und step die Werte der Ausdrücke sind, die als untere Grenze, obere Grenze und Schrittweite angegeben sind, wobei None für fehlende Ausdrücke eingesetzt wird.
6.3.4. Aufrufe¶
Ein Aufruf ruft ein aufrufbares Objekt (z. B. eine Funktion) mit einer möglicherweise leeren Reihe von Argumenten auf.
call:primary"(" [argument_list[","] |comprehension] ")" argument_list:positional_arguments[","starred_and_keywords] [","keywords_arguments] |starred_and_keywords[","keywords_arguments] |keywords_argumentspositional_arguments:positional_item(","positional_item)* positional_item:assignment_expression| "*"expressionstarred_and_keywords: ("*"expression|keyword_item) ("," "*"expression| ","keyword_item)* keywords_arguments: (keyword_item| "**"expression) (","keyword_item| "," "**"expression)* keyword_item:identifier"="expression
Ein optionales abschließendes Komma kann nach den positionellen und benannten Argumenten vorhanden sein, hat aber keinen Einfluss auf die Semantik.
Der primäre Ausdruck muss zu einem aufrufbaren Objekt ausgewertet werden (benutzerdefinierte Funktionen, eingebaute Funktionen, Methoden von eingebauten Objekten, Klassenobjekte, Methoden von Klasseninstanzen und alle Objekte, die eine __call__()-Methode haben, sind aufrufbar). Alle Argumentausdrücke werden ausgewertet, bevor der Aufruf versucht wird. Siehe Abschnitt Funktionsdefinitionen für die Syntax formaler Parameterlisten.
Wenn Schlüsselwortargumente vorhanden sind, werden diese zuerst in Positionsargumente umgewandelt, wie folgt. Zuerst wird eine Liste von nicht gefüllten Slots für die formalen Parameter erstellt. Wenn N Positionsargumente vorhanden sind, werden diese in die ersten N Slots platziert. Als Nächstes wird für jedes Schlüsselwortargument der Bezeichner verwendet, um den entsprechenden Slot zu ermitteln (wenn der Bezeichner mit dem ersten formalen Parameternamen übereinstimmt, wird der erste Slot verwendet und so weiter). Wenn der Slot bereits gefüllt ist, wird eine TypeError Ausnahme ausgelöst. Andernfalls wird das Argument in den Slot platziert und füllt ihn (auch wenn der Ausdruck None ist, füllt er den Slot). Wenn alle Argumente verarbeitet wurden, werden die noch nicht gefüllten Slots mit dem entsprechenden Standardwert aus der Funktionsdefinition gefüllt. (Standardwerte werden einmal berechnet, wenn die Funktion definiert wird; daher wird ein veränderliches Objekt wie eine Liste oder ein Wörterbuch, das als Standardwert verwendet wird, von allen Aufrufen gemeinsam genutzt, die keinen Argumentwert für den entsprechenden Slot angeben; dies sollte normalerweise vermieden werden.) Wenn es nicht gefüllte Slots gibt, für die kein Standardwert angegeben ist, wird eine TypeError Ausnahme ausgelöst. Andernfalls wird die Liste der gefüllten Slots als Argumentliste für den Aufruf verwendet.
CPython Implementierungsdetail: Eine Implementierung kann eingebaute Funktionen bereitstellen, deren Positionsargumente keine Namen haben, auch wenn sie zu Dokumentationszwecken "benannt" sind, und die daher nicht per Schlüsselwort übergeben werden können. In CPython ist dies bei Funktionen der Fall, die in C implementiert sind und PyArg_ParseTuple() zum Parsen ihrer Argumente verwenden.
Wenn mehr Positionsargumente vorhanden sind als formale Parameter-Slots, wird eine TypeError Ausnahme ausgelöst, es sei denn, ein formaler Parameter mit der Syntax *identifier ist vorhanden; in diesem Fall empfängt dieser formale Parameter ein Tupel, das die überschüssigen Positionsargumente enthält (oder ein leeres Tupel, wenn keine überschüssigen Positionsargumente vorhanden waren).
Wenn ein Schlüsselwortargument nicht mit einem formalen Parameternamen übereinstimmt, wird eine TypeError Ausnahme ausgelöst, es sei denn, ein formaler Parameter mit der Syntax **identifier ist vorhanden; in diesem Fall empfängt dieser formale Parameter ein Wörterbuch, das die überschüssigen Schlüsselwortargumente enthält (wobei die Schlüssel als Schlüssel und die Argumentwerte als entsprechende Werte verwendet werden) oder ein (neues) leeres Wörterbuch, wenn keine überschüssigen Schlüsselwortargumente vorhanden waren.
Wenn die Syntax *expression im Funktionsaufruf erscheint, muss expression zu einem iterierbaren Objekt ausgewertet werden. Elemente aus diesen iterierbaren Objekten werden so behandelt, als wären sie zusätzliche Positionsargumente. Für den Aufruf f(x1, x2, *y, x3, x4), wenn y zu einer Sequenz y1, …, yM ausgewertet wird, ist dies äquivalent zu einem Aufruf mit M+4 Positionsargumenten x1, x2, y1, …, yM, x3, x4.
Eine Folge davon ist, dass, obwohl die *expression-Syntax nach expliziten Schlüsselwortargumenten erscheinen kann, sie vor den Schlüsselwortargumenten (und allen **expression-Argumenten – siehe unten) verarbeitet wird. Also
>>> def f(a, b):
... print(a, b)
...
>>> f(b=1, *(2,))
2 1
>>> f(a=1, *(2,))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() got multiple values for keyword argument 'a'
>>> f(1, *(2,))
1 2
Es ist ungewöhnlich, dass sowohl Schlüsselwortargumente als auch die *expression-Syntax im selben Aufruf verwendet werden, so dass diese Verwirrung in der Praxis nicht oft auftritt.
Wenn die Syntax **expression im Funktionsaufruf erscheint, muss expression zu einer Abbildung ausgewertet werden, deren Inhalte als zusätzliche Schlüsselwortargumente behandelt werden. Wenn einem Parameter, der zu einem Schlüssel passt, bereits ein Wert zugewiesen wurde (durch ein explizites Schlüsselwortargument oder aus einer anderen Entpackung), wird eine TypeError Ausnahme ausgelöst.
Wenn **expression verwendet wird, muss jeder Schlüssel in dieser Abbildung ein String sein. Jeder Wert aus der Abbildung wird dem ersten formalen Parameter zugewiesen, der für die Schlüsselwortzuweisung in Frage kommt und dessen Name mit dem Schlüssel übereinstimmt. Ein Schlüssel muss kein Python-Bezeichner sein (z.B. ist "max-temp °F" akzeptabel, obwohl er keinem formalen Parameter entspricht, der deklariert werden könnte). Wenn keine Übereinstimmung mit einem formalen Parameter gefunden wird, wird das Schlüssel-Wert-Paar vom **-Parameter gesammelt, falls einer vorhanden ist, oder andernfalls wird eine TypeError Ausnahme ausgelöst.
Formale Parameter, die die Syntax *identifier oder **identifier verwenden, können nicht als Positionsargument-Slots oder als Schlüsselwortargument-Namen verwendet werden.
Geändert in Version 3.5: Funktionsaufrufe akzeptieren eine beliebige Anzahl von * und **-Entpackungen, Positionsargumente können auf iterierbare Entpackungen (*) folgen, und Schlüsselwortargumente können auf Dictionary-Entpackungen (**) folgen. Ursprünglich vorgeschlagen von PEP 448.
Ein Aufruf gibt immer einen Wert zurück, möglicherweise None, es sei denn, er löst eine Ausnahme aus. Wie dieser Wert berechnet wird, hängt vom Typ des aufrufbaren Objekts ab.
Wenn es sich um—
- eine benutzerdefinierte Funktion
Der Codeblock der Funktion wird ausgeführt und ihr die Argumentliste übergeben. Das erste, was der Codeblock tut, ist, die formalen Parameter an die Argumente zu binden; dies ist in Abschnitt Funktionsdefinitionen beschrieben. Wenn der Codeblock eine
return-Anweisung ausführt, gibt dies den Rückgabewert des Funktionsaufrufs an. Wenn die Ausführung das Ende des Codeblocks erreicht, ohne einereturn-Anweisung auszuführen, ist der RückgabewertNone.- eine eingebaute Funktion oder Methode
Das Ergebnis liegt beim Interpreter; siehe Eingebaute Funktionen für die Beschreibungen der eingebauten Funktionen und Methoden.
- ein Klassenobjekt
Eine neue Instanz dieser Klasse wird zurückgegeben.
- eine Klasseninstanzmethode
Die entsprechende benutzerdefinierte Funktion wird mit einer Argumentliste aufgerufen, die um eins länger ist als die Argumentliste des Aufrufs: die Instanz wird zum ersten Argument.
- eine Klasseninstanz
Die Klasse muss eine
__call__()-Methode definieren; die Auswirkung ist dann die gleiche, als ob diese Methode aufgerufen worden wäre.
6.4. Await-Ausdruck¶
Suspendiert die Ausführung einer Coroutine auf einem awaitable-Objekt. Kann nur innerhalb einer Coroutine-Funktion verwendet werden.
await_expr: "await" primary
Hinzugefügt in Version 3.5.
6.5. Der Potenzierungsoperator¶
Der Potenzierungsoperator bindet stärker als unäre Operatoren links davon; er bindet weniger stark als unäre Operatoren rechts davon. Die Syntax ist
power: (await_expr|primary) ["**"u_expr]
Daher werden in einer nicht geklammerten Sequenz von Potenzierungs- und unären Operatoren die Operatoren von rechts nach links ausgewertet (dies schränkt die Auswertungsreihenfolge für die Operanden nicht ein): -1**2 ergibt -1.
Der Potenzierungsoperator hat die gleiche Semantik wie die eingebaute Funktion pow(), wenn sie mit zwei Argumenten aufgerufen wird: sie gibt ihr linkes Argument potenziert mit ihrem rechten Argument zurück. Die numerischen Argumente werden zuerst in einen gemeinsamen Typ konvertiert, und das Ergebnis hat diesen Typ.
Für int-Operanden hat das Ergebnis den gleichen Typ wie die Operanden, es sei denn, das zweite Argument ist negativ; in diesem Fall werden alle Argumente in float konvertiert und ein float-Ergebnis geliefert. Zum Beispiel gibt 10**2 100 zurück, aber 10**-2 gibt 0.01 zurück.
Das Potenzieren von 0.0 mit einer negativen Potenz führt zu einer ZeroDivisionError. Das Potenzieren einer negativen Zahl mit einer gebrochenen Potenz führt zu einer complex-Zahl. (In früheren Versionen wurde eine ValueError ausgelöst.)
Diese Operation kann über die speziellen Methoden __pow__() und __rpow__() angepasst werden.
6.6. Unäre arithmetische und bitweise Operationen¶
Alle unären arithmetischen und bitweisen Operationen haben die gleiche Priorität
u_expr:power| "-"u_expr| "+"u_expr| "~"u_expr
Der unäre Operator - (Minus) gibt die Negation seines numerischen Arguments zurück; die Operation kann über die spezielle Methode __neg__() überschrieben werden.
Der unäre Operator + (Plus) gibt sein numerisches Argument unverändert zurück; die Operation kann über die spezielle Methode __pos__() überschrieben werden.
Der unäre Operator ~ (invertieren) gibt die bitweise Invertierung seines ganzzahligen Arguments zurück. Die bitweise Invertierung von x ist definiert als -(x+1). Sie gilt nur für ganzzahlige Zahlen oder für benutzerdefinierte Objekte, die die spezielle Methode __invert__() überschreiben.
In allen drei Fällen wird, wenn das Argument nicht den richtigen Typ hat, eine TypeError Ausnahme ausgelöst.
6.7. Binäre arithmetische Operationen¶
Die binären arithmetischen Operationen haben die konventionellen Prioritätsstufen. Beachten Sie, dass einige dieser Operationen auch auf bestimmte nicht-numerische Typen angewendet werden. Abgesehen vom Potenzierungsoperator gibt es nur zwei Stufen, eine für multiplikative Operatoren und eine für additive Operatoren
m_expr:u_expr|m_expr"*"u_expr|m_expr"@"m_expr|m_expr"//"u_expr|m_expr"/"u_expr|m_expr"%"u_expra_expr:m_expr|a_expr"+"m_expr|a_expr"-"m_expr
Der Operator * (Multiplikation) ergibt das Produkt seiner Argumente. Die Argumente müssen entweder beide Zahlen sein, oder ein Argument muss eine Ganzzahl und das andere eine Sequenz sein. Im ersteren Fall werden die Zahlen in einen gemeinsamen realen Typ konvertiert und dann miteinander multipliziert. Im letzteren Fall wird die Sequenzwiederholung durchgeführt; ein negativer Wiederholungsfaktor ergibt eine leere Sequenz.
Diese Operation kann über die speziellen Methoden __mul__() und __rmul__() angepasst werden.
Geändert in Version 3.14: Wenn nur ein Operand eine komplexe Zahl ist, wird der andere Operand in eine Gleitkommazahl konvertiert.
Der Operator @ (at) ist für die Matrixmultiplikation vorgesehen. Keine eingebauten Python-Typen implementieren diesen Operator.
Diese Operation kann über die speziellen Methoden __matmul__() und __rmatmul__() angepasst werden.
Hinzugefügt in Version 3.5.
Die Operatoren / (Division) und // (Ganzzahl-Division) ergeben den Quotienten ihrer Argumente. Die numerischen Argumente werden zuerst in einen gemeinsamen Typ konvertiert. Die Division von ganzen Zahlen ergibt eine Gleitkommazahl, während die Ganzzahl-Division von ganzen Zahlen eine ganze Zahl ergibt; das Ergebnis ist das der mathematischen Division mit der angewendeten 'floor'-Funktion. Die Division durch Null löst die Ausnahme ZeroDivisionError aus.
Die Divisionsoperation kann über die speziellen Methoden __truediv__() und __rtruediv__() angepasst werden. Die Ganzzahl-Divisionsoperation kann über die speziellen Methoden __floordiv__() und __rfloordiv__() angepasst werden.
Der Operator % (Modulo) ergibt den Rest der Division des ersten Arguments durch das zweite. Die numerischen Argumente werden zuerst in einen gemeinsamen Typ konvertiert. Ein rechtes Argument von Null löst die Ausnahme ZeroDivisionError aus. Die Argumente können Gleitkommazahlen sein, z.B. ergibt 3.14%0.7 0.34 (da 3.14 gleich 4*0.7 + 0.34 ist). Der Modulo-Operator gibt immer ein Ergebnis mit dem gleichen Vorzeichen wie sein zweites Argument (oder Null) zurück; der Absolutwert des Ergebnisses ist strikt kleiner als der Absolutwert des zweiten Arguments [1].
Die Ganzzahl-Division und der Modulo-Operator sind durch die folgende Identität verbunden: x == (x//y)*y + (x%y). Ganzzahl-Division und Modulo sind auch mit der eingebauten Funktion divmod() verbunden: divmod(x, y) == (x//y, x%y). [2].
Neben der Durchführung der Modulo-Operation auf Zahlen wird der Operator % auch von String-Objekten überladen, um die alte String-Formatierung (auch als Interpolation bekannt) durchzuführen. Die Syntax für die String-Formatierung ist im Python Library Reference, Abschnitt Printf-style String Formatting beschrieben.
Die Modulo-Operation kann über die speziellen Methoden __mod__() und __rmod__() angepasst werden.
Der Ganzzahl-Divisionsoperator, der Modulo-Operator und die Funktion divmod() sind für komplexe Zahlen nicht definiert. Stattdessen konvertieren Sie in eine Gleitkommazahl, indem Sie gegebenenfalls die Funktion abs() verwenden.
Der Operator + (Addition) ergibt die Summe seiner Argumente. Die Argumente müssen entweder beide Zahlen oder beide Sequenzen vom gleichen Typ sein. Im ersteren Fall werden die Zahlen in einen gemeinsamen realen Typ konvertiert und dann addiert. Im letzteren Fall werden die Sequenzen verkettet.
Diese Operation kann über die speziellen Methoden __add__() und __radd__() angepasst werden.
Geändert in Version 3.14: Wenn nur ein Operand eine komplexe Zahl ist, wird der andere Operand in eine Gleitkommazahl konvertiert.
Der Operator - (Subtraktion) ergibt die Differenz seiner Argumente. Die numerischen Argumente werden zuerst in einen gemeinsamen realen Typ konvertiert.
Diese Operation kann über die speziellen Methoden __sub__() und __rsub__() angepasst werden.
Geändert in Version 3.14: Wenn nur ein Operand eine komplexe Zahl ist, wird der andere Operand in eine Gleitkommazahl konvertiert.
6.8. Schiebeoperationen¶
Die Schiebeoperationen haben eine geringere Priorität als die arithmetischen Operationen
shift_expr:a_expr|shift_expr("<<" | ">>")a_expr
Diese Operatoren akzeptieren ganze Zahlen als Argumente. Sie verschieben das erste Argument nach links oder rechts um die Anzahl der Bits, die durch das zweite Argument angegeben wird.
Die Links-Schiebeoperation kann über die speziellen Methoden __lshift__() und __rlshift__() angepasst werden. Die Rechts-Schiebeoperation kann über die speziellen Methoden __rshift__() und __rrshift__() angepasst werden.
Eine Rechtsverschiebung um n Bits ist definiert als Ganzzahl-Division durch pow(2,n). Eine Linksverschiebung um n Bits ist definiert als Multiplikation mit pow(2,n).
6.9. Binäre bitweise Operationen¶
Jede der drei bitweisen Operationen hat eine unterschiedliche Prioritätsstufe
and_expr:shift_expr|and_expr"&"shift_exprxor_expr:and_expr|xor_expr"^"and_expror_expr:xor_expr|or_expr"|"xor_expr
Der Operator & ergibt das bitweise AND seiner Argumente, die ganze Zahlen sein müssen oder von denen eine ein benutzerdefiniertes Objekt sein muss, das die speziellen Methoden __and__() oder __rand__() überschreibt.
Der Operator ^ ergibt das bitweise XOR (Exklusiv-ODER) seiner Argumente, die ganze Zahlen sein müssen oder von denen eine ein benutzerdefiniertes Objekt sein muss, das die speziellen Methoden __xor__() oder __rxor__() überschreibt.
Der Operator | ergibt das bitweise (inklusive) ODER seiner Argumente, die ganze Zahlen sein müssen oder von denen eine ein benutzerdefiniertes Objekt sein muss, das die speziellen Methoden __or__() oder __ror__() überschreibt.
6.10. Vergleiche¶
Im Gegensatz zu C haben alle Vergleichsoperationen in Python die gleiche Priorität, die niedriger ist als die jeder arithmetischen, schiebenden oder bitweisen Operation. Ebenso im Gegensatz zu C werden Ausdrücke wie a < b < c so interpretiert, wie es in der Mathematik üblich ist
comparison:or_expr(comp_operatoror_expr)* comp_operator: "<" | ">" | "==" | ">=" | "<=" | "!=" | "is" ["not"] | ["not"] "in"
Vergleiche ergeben boolesche Werte: True oder False. Benutzerdefinierte rich comparison methods können nicht-boolesche Werte zurückgeben. In diesem Fall ruft Python bool() auf diesen Wert in booleschen Kontexten auf.
Vergleiche können beliebig verknüpft werden, z.B. x < y <= z ist äquivalent zu x < y and y <= z, außer dass y nur einmal ausgewertet wird (aber in beiden Fällen wird z nicht ausgewertet, wenn x < y als falsch befunden wird).
Formal, wenn a, b, c, …, y, z Ausdrücke sind und op1, op2, …, opN Vergleichsoperatoren sind, dann ist a op1 b op2 c ... y opN z äquivalent zu a op1 b and b op2 c and ... y opN z, außer dass jeder Ausdruck höchstens einmal ausgewertet wird.
Beachten Sie, dass a op1 b op2 c keinen Vergleich zwischen a und c impliziert, so dass z.B. x < y > z vollkommen legal (wenn auch vielleicht nicht schön) ist.
6.10.1. Wertvergleiche¶
Die Operatoren <, >, ==, >=, <= und != vergleichen die Werte zweier Objekte. Die Objekte müssen nicht den gleichen Typ haben.
Kapitel Objekte, Werte und Typen besagt, dass Objekte einen Wert haben (zusätzlich zu Typ und Identität). Der Wert eines Objekts ist in Python eine eher abstrakte Vorstellung: Es gibt beispielsweise keine kanonische Zugriffsmethode auf den Wert eines Objekts. Ebenso gibt es keine Anforderung, dass der Wert eines Objekts auf eine bestimmte Weise konstruiert sein muss, z.B. aus all seinen Datenattributen. Vergleichsoperatoren implementieren eine bestimmte Vorstellung davon, was der Wert eines Objekts ist. Man kann sie sich als indirekte Definition des Objektwerts vorstellen, mittels ihrer Vergleichsimplementierung.
Da alle Typen (direkte oder indirekte) Untertypen von object sind, erben sie das Standard-Vergleichsverhalten von object. Typen können ihr Vergleichsverhalten anpassen, indem sie rich comparison methods wie __lt__() implementieren, wie in Grundlegende Anpassung beschrieben.
Das Standardverhalten für den Gleichheitsvergleich (== und !=) basiert auf der Identität der Objekte. Daher führt der Gleichheitsvergleich von Instanzen mit derselben Identität zu Gleichheit, und der Gleichheitsvergleich von Instanzen mit unterschiedlichen Identitäten führt zu Ungleichheit. Eine Motivation für dieses Standardverhalten ist der Wunsch, dass alle Objekte reflexiv sein sollen (d.h. x is y impliziert x == y).
Ein Standard-Ordnungsvergleich (<, >, <= und >=) wird nicht bereitgestellt; ein Versuch löst eine TypeError Ausnahme aus. Eine Motivation für dieses Standardverhalten ist das Fehlen einer ähnlichen Invariante wie bei der Gleichheit.
Das Verhalten des standardmäßigen Gleichheitsvergleichs, dass Instanzen mit unterschiedlichen Identitäten immer ungleich sind, kann im Gegensatz zu dem stehen, was Typen benötigen, die eine sinnvolle Definition von Objektwert und wertbasierter Gleichheit haben. Solche Typen müssen ihr Vergleichsverhalten anpassen, und tatsächlich haben eine Reihe von integrierten Typen dies getan.
Die folgende Liste beschreibt das Vergleichsverhalten der wichtigsten integrierten Typen.
Zahlen von integrierten numerischen Typen (Numerische Typen — int, float, complex) und der Standardbibliothekstypen
fractions.Fractionunddecimal.Decimalkönnen innerhalb und über ihre Typen hinweg verglichen werden, mit der Einschränkung, dass komplexe Zahlen keinen Ordnungsvergleich unterstützen. Innerhalb der Grenzen der beteiligten Typen vergleichen sie sich mathematisch (algorithmisch) korrekt und ohne Präzisionsverlust.Die Nicht-eine-Zahl-Werte
float('NaN')unddecimal.Decimal('NaN')sind besonders. Jeder geordnete Vergleich einer Zahl mit einem Nicht-eine-Zahl-Wert ist falsch. Eine kontraintuitive Implikation ist, dass Nicht-eine-Zahl-Werte nicht gleich sich selbst sind. Zum Beispiel, wennx = float('NaN'), sind3 < x,x < 3undx == xalle falsch, währendx != xwahr ist. Dieses Verhalten entspricht IEEE 754.NoneundNotImplementedsind Singletons. PEP 8 rät dazu, Vergleiche von Singletons immer mitisoderis notdurchzuführen, niemals mit Gleichheitsoperatoren.Binäre Sequenzen (Instanzen von
bytesoderbytearray) können innerhalb und über ihre Typen hinweg verglichen werden. Sie vergleichen sich lexikographisch anhand der numerischen Werte ihrer Elemente.Zeichenketten (Instanzen von
str) vergleichen sich lexikographisch anhand der numerischen Unicode-Codepunkte (dem Ergebnis der integrierten Funktionord()) ihrer Zeichen. [3]Zeichenketten und binäre Sequenzen können nicht direkt verglichen werden.
Sequenzen (Instanzen von
tuple,listoderrange) können nur innerhalb jedes ihrer Typen verglichen werden, mit der Einschränkung, dass Bereiche keinen Ordnungsvergleich unterstützen. Gleichheitsvergleiche über diese Typen hinweg führen zu Ungleichheit, und Ordnungsvergleiche über diese Typen hinweg lösen einenTypeErroraus.Sequenzen vergleichen sich lexikographisch anhand des Vergleichs entsprechender Elemente. Die integrierten Container nehmen typischerweise an, dass identische Objekte gleich sich selbst sind. Das erlaubt ihnen, Gleichheitstests für identische Objekte zu umgehen, um die Leistung zu verbessern und ihre internen Invarianten aufrechtzuerhalten.
Lexikographische Vergleiche zwischen integrierten Sammlungen funktionieren wie folgt:
Damit zwei Sammlungen als gleich gelten, müssen sie vom selben Typ sein, die gleiche Länge haben und jedes Paar entsprechender Elemente muss gleich sein (z. B. ist
[1,2] == (1,2)falsch, da der Typ nicht derselbe ist).Sammlungen, die den Ordnungsvergleich unterstützen, werden so geordnet wie ihre ersten ungleichen Elemente (z. B. hat
[1,2,x] <= [1,2,y]denselben Wert wiex <= y). Wenn ein entsprechendes Element nicht existiert, wird die kürzere Sammlung zuerst geordnet (z. B. ist[1,2] < [1,2,3]wahr).
Abbildungen (Instanzen von
dict) sind genau dann gleich, wenn sie gleiche(key, value)-Paare haben. Der Gleichheitsvergleich der Schlüssel und Werte erzwingt Reflexivität.Ordnungsvergleiche (
<,>,<=und>=) lösen einenTypeErroraus.Mengen (Instanzen von
setoderfrozenset) können innerhalb und über ihre Typen hinweg verglichen werden.Sie definieren Ordnungsvergleichsoperatoren für Teilmengen- und Obermengen-Tests. Diese Relationen definieren keine totale Ordnung (z. B. sind die beiden Mengen
{1,2}und{2,3}nicht gleich, noch Teilmengen voneinander, noch Obermengen voneinander). Folglich sind Mengen keine geeigneten Argumente für Funktionen, die auf totaler Ordnung basieren (z. B. erzeugenmin(),max()undsorted()undefinierte Ergebnisse bei einer Liste von Mengen als Eingaben).Der Vergleich von Mengen erzwingt die Reflexivität seiner Elemente.
Die meisten anderen integrierten Typen haben keine Vergleichsmethoden implementiert, sodass sie das standardmäßige Vergleichsverhalten erben.
Benutzerdefinierte Klassen, die ihr Vergleichsverhalten anpassen, sollten, wenn möglich, einige Konsistenzregeln befolgen.
Gleichheitsvergleich sollte reflexiv sein. Mit anderen Worten, identische Objekte sollten gleich verglichen werden.
x is yimpliziertx == y.Vergleich sollte symmetrisch sein. Mit anderen Worten, die folgenden Ausdrücke sollten das gleiche Ergebnis haben:
x == yundy == x.x != yundy != x.x < yundy > x.x <= yundy >= x.Vergleich sollte transitiv sein. Die folgenden (nicht erschöpfenden) Beispiele veranschaulichen dies:
x > y and y > zimpliziertx > z.x < y and y <= zimpliziertx < z.Der umgekehrte Vergleich sollte zur booleschen Negation führen. Mit anderen Worten, die folgenden Ausdrücke sollten das gleiche Ergebnis haben:
x == yundnot x != y.x < yundnot x >= y(für totale Ordnung).x > yundnot x <= y(für totale Ordnung).Die letzten beiden Ausdrücke gelten für total geordnete Sammlungen (z. B. für Sequenzen, aber nicht für Mengen oder Abbildungen). Siehe auch den
total_ordering()Dekorator.Das Ergebnis von
hash()sollte mit der Gleichheit übereinstimmen. Gleiche Objekte sollten entweder den gleichen Hash-Wert haben oder als nicht haschbar markiert sein.
Python erzwingt diese Konsistenzregeln nicht. Tatsächlich sind die Nicht-eine-Zahl-Werte ein Beispiel dafür, dass diese Regeln nicht befolgt werden.
6.10.2. Mitgliedschaftstest-Operationen¶
Die Operatoren in und not in testen auf Mitgliedschaft. x in s ergibt True, wenn x ein Mitglied von s ist, und andernfalls False. x not in s gibt die Negation von x in s zurück. Alle integrierten Sequenzen und Mengen unterstützen dies, ebenso Wörterbücher, für die in testet, ob das Wörterbuch einen bestimmten Schlüssel hat. Für Containertypen wie Listen, Tupel, Mengen, Frozensets, Dictionaries oder collections.deque ist der Ausdruck x in y äquivalent zu any(x is e or x == e for e in y).
Für die Zeichenketten- und Bytes-Typen ist x in y genau dann wahr, wenn x eine Teilzeichenkette von y ist. Ein äquivalenter Test ist y.find(x) != -1. Leere Zeichenketten gelten immer als Teilzeichenkette einer beliebigen anderen Zeichenkette, daher gibt "" in "abc" True zurück.
Für benutzerdefinierte Klassen, die die Methode __contains__() definieren, gibt x in y True zurück, wenn y.__contains__(x) einen wahren Wert zurückgibt, und andernfalls False.
Für benutzerdefinierte Klassen, die __contains__() nicht definieren, aber __iter__() definieren, ist x in y wahr, wenn ein Wert z, für den der Ausdruck x is z or x == z wahr ist, während der Iteration über y erzeugt wird. Wenn während der Iteration eine Ausnahme ausgelöst wird, ist es so, als ob in diese Ausnahme ausgelöst hätte.
Zuletzt wird das alte Iterationsprotokoll versucht: Wenn eine Klasse __getitem__() definiert, ist x in y wahr, wenn und nur wenn es einen nicht-negativen ganzzahligen Index i gibt, so dass x is y[i] or x == y[i] und kein kleinerer ganzzahliger Index die IndexError Ausnahme auslöst. (Wenn eine andere Ausnahme ausgelöst wird, ist es so, als ob in diese Ausnahme ausgelöst hätte).
Der Operator not in ist so definiert, dass er den umgekehrten Wahrheitswert von in hat.
6.10.3. Identitätsvergleiche¶
Die Operatoren is und is not testen die Identität eines Objekts: x is y ist wahr genau dann, wenn x und y dasselbe Objekt sind. Die Identität eines Objekts wird mit der Funktion id() bestimmt. x is not y ergibt den umgekehrten Wahrheitswert. [4]
6.11. Boolesche Operationen¶
or_test:and_test|or_test"or"and_testand_test:not_test|and_test"and"not_testnot_test:comparison| "not"not_test
Im Kontext boolescher Operationen und auch wenn Ausdrücke von Kontrollflussanweisungen verwendet werden, werden die folgenden Werte als falsch interpretiert: False, None, numerischer Nullwert aller Typen sowie leere Zeichenketten und leere Container (einschließlich Zeichenketten, Tupel, Listen, Wörterbücher, Mengen und Frozensets). Alle anderen Werte werden als wahr interpretiert. Benutzerdefinierte Objekte können ihren Wahrheitswert durch Bereitstellung einer __bool__()-Methode anpassen.
Der Operator not gibt True zurück, wenn sein Argument falsch ist, andernfalls False.
Der Ausdruck x and y wertet zuerst x aus; wenn x falsch ist, wird sein Wert zurückgegeben; andernfalls wird y ausgewertet und der resultierende Wert zurückgegeben.
Der Ausdruck x or y wertet zuerst x aus; wenn x wahr ist, wird sein Wert zurückgegeben; andernfalls wird y ausgewertet und der resultierende Wert zurückgegeben.
Beachten Sie, dass weder and noch or den Wert und Typ, den sie zurückgeben, auf False und True beschränken, sondern stattdessen das zuletzt ausgewertete Argument zurückgeben. Dies ist manchmal nützlich, z. B. wenn s eine Zeichenkette ist, die durch einen Standardwert ersetzt werden soll, wenn sie leer ist, gibt der Ausdruck s or 'foo' den gewünschten Wert zurück. Da not einen neuen Wert erzeugen muss, gibt es unabhängig vom Typ seines Arguments einen booleschen Wert zurück (z. B. erzeugt not 'foo' False und nicht '').
6.12. Zuweisungsausdrücke¶
assignment_expression: [identifier":="]expression
Ein Zuweisungsausdruck (manchmal auch als „benannter Ausdruck“ oder „Walross-Operator“ bezeichnet) weist einen Ausdruck einem Bezeichner zu, gibt aber gleichzeitig den Wert des Ausdrucks zurück.
Ein häufiger Anwendungsfall ist die Verarbeitung von regulären Ausdrücken, die übereinstimmen.
if matching := pattern.search(data):
do_something(matching)
Oder bei der Verarbeitung eines Dateistroms in Blöcken.
while chunk := file.read(9000):
process(chunk)
Zuweisungsausdrücke müssen in Klammern gesetzt werden, wenn sie als Ausdrucksanweisungen verwendet werden und wenn sie als Unterausdrücke in Slicing-, bedingten Ausdrücken, Lambda-Ausdrücken, Schlüsselwortargumenten und Comprehension-if-Ausdrücken sowie in `assert`-, `with`- und `Zuweisungsanweisungen` verwendet werden. An allen anderen Stellen, wo sie verwendet werden können, sind Klammern nicht erforderlich, einschließlich in `if`- und `while`-Anweisungen.
Hinzugefügt in Version 3.8: Siehe PEP 572 für weitere Details zu Zuweisungsausdrücken.
6.13. Bedingte Ausdrücke¶
conditional_expression:or_test["if"or_test"else"expression] expression:conditional_expression|lambda_expr
Ein bedingter Ausdruck (manchmal auch als „ternärer Operator“ bezeichnet) ist eine Alternative zur if-else-Anweisung. Da es sich um einen Ausdruck handelt, gibt er einen Wert zurück und kann als Unterausdruck erscheinen.
Der Ausdruck x if C else y wertet zuerst die Bedingung C aus, anstatt x. Wenn C wahr ist, wird x ausgewertet und sein Wert zurückgegeben; andernfalls wird y ausgewertet und sein Wert zurückgegeben.
Siehe PEP 308 für weitere Details zu bedingten Ausdrücken.
6.14. Lambdas¶
lambda_expr: "lambda" [parameter_list] ":"expression
Lambda-Ausdrücke (manchmal auch Lambda-Formen genannt) werden verwendet, um anonyme Funktionen zu erstellen. Der Ausdruck lambda parameters: expression liefert ein Funktionsobjekt. Das unbenannte Objekt verhält sich wie ein Funktionsobjekt, das definiert wurde mit:
def <lambda>(parameters):
return expression
Siehe Abschnitt Funktionsdefinitionen für die Syntax von Parameterlisten. Beachten Sie, dass mit Lambda-Ausdrücken erstellte Funktionen keine Anweisungen oder Annotationen enthalten können.
6.15. Ausdruckslisten¶
starred_expression: "*"or_expr|expressionflexible_expression:assignment_expression|starred_expressionflexible_expression_list:flexible_expression(","flexible_expression)* [","] starred_expression_list:starred_expression(","starred_expression)* [","] expression_list:expression(","expression)* [","] yield_list:expression_list|starred_expression"," [starred_expression_list]
Außer wenn sie Teil einer Listen- oder Mengenanzeige sind, liefert eine Ausdrucksliste, die mindestens ein Komma enthält, ein Tupel. Die Länge des Tupels entspricht der Anzahl der Ausdrücke in der Liste. Die Ausdrücke werden von links nach rechts ausgewertet.
Ein Sternchen * bezeichnet Iterable-Entpackung. Sein Operand muss ein Iterable sein. Das Iterable wird in eine Sequenz von Elementen erweitert, die am Ort der Entpackung in das neue Tupel, die neue Liste oder die neue Menge aufgenommen werden.
Hinzugefügt in Version 3.5: Iterable-Entpackung in Ausdruckslisten, ursprünglich vorgeschlagen durch PEP 448.
Hinzugefügt in Version 3.11: Jedes Element einer Ausdrucksliste kann mit einem Sternchen versehen werden. Siehe PEP 646.
Ein nachgestelltes Komma ist nur erforderlich, um ein Tupel mit einem Element zu erstellen, z. B. 1,; in allen anderen Fällen ist es optional. Ein einzelner Ausdruck ohne nachgestelltes Komma erstellt kein Tupel, sondern liefert den Wert dieses Ausdrucks. (Um ein leeres Tupel zu erstellen, verwenden Sie ein leeres Klammernpaar: ().)
6.16. Auswertungsreihenfolge¶
Python wertet Ausdrücke von links nach rechts aus. Beachten Sie, dass während der Auswertung einer Zuweisung die rechte Seite vor der linken Seite ausgewertet wird.
In den folgenden Zeilen werden Ausdrücke in der arithmetischen Reihenfolge ihrer Suffixe ausgewertet.
expr1, expr2, expr3, expr4
(expr1, expr2, expr3, expr4)
{expr1: expr2, expr3: expr4}
expr1 + expr2 * (expr3 - expr4)
expr1(expr2, expr3, *expr4, **expr5)
expr3, expr4 = expr1, expr2
6.17. Operatorrangfolge¶
Die folgende Tabelle fasst die Operatorrangfolge in Python zusammen, von der höchsten Rangfolge (am stärksten bindend) bis zur niedrigsten Rangfolge (am schwächsten bindend). Operatoren in derselben Box haben die gleiche Rangfolge. Sofern die Syntax nicht explizit angegeben ist, sind Operatoren binär. Operatoren in derselben Box gruppieren sich von links nach rechts (außer bei Exponentiation und bedingten Ausdrücken, die sich von rechts nach links gruppieren).
Beachten Sie, dass Vergleiche, Mitgliedschaftstests und Identitätstests alle die gleiche Rangfolge haben und eine Verketten von links nach rechts bieten, wie im Abschnitt Vergleiche beschrieben.
Operator |
Beschreibung |
|---|---|
|
Bindender oder geklammerter Ausdruck, Listenanzeige, Wörterbuchanzeige, Mengenanzeige |
|
Subskription, Slicing, Aufruf, Attributreferenz |
Await-Ausdruck |
|
|
Exponentiation [5] |
|
Positiv, negativ, bitweises NICHT |
|
Multiplikation, Matrixmultiplikation, Division, Ganzzahlige Division, Rest [6] |
|
Addition und Subtraktion |
|
Schiebeoperationen |
|
Bitweises UND |
|
Bitweises XOR |
|
Bitweises ODER |
Vergleiche, einschließlich Mitgliedschaftstests und Identitätstests |
|
Boolesches NICHT |
|
Boolesches UND |
|
Boolesches ODER |
|
|
Bedingter Ausdruck |
Lambda-Ausdruck |
|
|
Zuweisungsausdruck |
Fußnoten