8. Zusammengesetzte Anweisungen
*******************************

Zusammengesetzte Anweisungen enthalten (Gruppen von) anderen
Anweisungen; sie beeinflussen oder steuern in gewisser Weise die
Ausführung dieser anderen Anweisungen. Im Allgemeinen erstrecken sich
zusammengesetzte Anweisungen über mehrere Zeilen, obwohl in einfachen
Fällen eine gesamte zusammengesetzte Anweisung auch in einer einzigen
Zeile enthalten sein kann.

Die Anweisungen "if", "while" und "for" implementieren traditionelle
Kontrollflusskonstrukte. "try" legt Ausnahmebehandler und/oder
Aufräumcode für eine Gruppe von Anweisungen fest, während die
Anweisung "with" die Ausführung von Initialisierungs- und
Finalisierungscode um einen Codeblock herum ermöglicht. Funktions- und
Klassendefinitionen sind syntaktisch ebenfalls zusammengesetzte
Anweisungen.

Eine zusammengesetzte Anweisung besteht aus einer oder mehreren
"Klauseln". Eine Klausel besteht aus einer Überschrift und einer
"Suite". Die Klauselüberschriften einer bestimmten zusammengesetzten
Anweisung befinden sich alle auf derselben Einrückungsebene. Jede
Klauselüberschrift beginnt mit einem eindeutig identifizierenden
Schlüsselwort und endet mit einem Doppelpunkt.  Eine Suite ist eine
Gruppe von Anweisungen, die von einer Klausel gesteuert werden.  Eine
Suite kann aus einer oder mehreren durch Semikolons getrennten
einfachen Anweisungen bestehen, die sich in derselben Zeile wie die
Überschrift befinden und auf den Doppelpunkt der Überschrift folgen,
oder aus einer oder mehreren eingerückten Anweisungen in den folgenden
Zeilen.  Nur die letztgenannte Form einer Suite darf verschachtelte
zusammengesetzte Anweisungen enthalten; das folgende Beispiel ist
unzulässig, vor allem weil unklar wäre, zu welcher "if" -Klausel eine
nachfolgende "else" -Klausel gehören würde:

   if test1: if test2: print(x)

Beachten Sie außerdem, dass das Semikolon in diesem Zusammenhang eine
stärkere Bindung hat als der Doppelpunkt, sodass im folgenden Beispiel
entweder alle oder gar keine der "print()" -Aufrufe ausgeführt werden:

   Wenn x < y < z: print(x); print(y); print(z)

Zusammenfassend lässt sich sagen:

   compound_stmt ::= if_stmt
                     | while_stmt
                     | for_stmt
                     | try_stmt
                     | with_stmt
                     | match_stmt
                     | funcdef
                     | classdef
                     | async_with_stmt
                     | async_for_stmt
                     | async_funcdef
   suite         ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
   statement     ::= stmt_list NEWLINE | compound_stmt
   stmt_list     ::= simple_stmt (";" simple_stmt)* [";"]

Beachten Sie, dass Anweisungen immer mit einem "NEWLINE" enden, auf
das möglicherweise ein "DEDENT" folgt. Beachten Sie außerdem, dass
optionale Fortsetzungsklauseln immer mit einem Schlüsselwort beginnen,
das keine Anweisung einleiten darf, sodass keine Mehrdeutigkeiten
entstehen (das Problem der dangling "else" wird in Python dadurch
gelöst, dass verschachtelte "if" -Anweisungen eingerückt sein müssen).

Zur besseren Übersichtlichkeit werden die Grammatikregeln in den
folgenden Abschnitten so formatiert, dass jeder Satzteil in einer
eigenen Zeile steht.


8.1. Die  "if" Anweisung
========================

Die Anweisung "if" wird für die bedingte Ausführung verwendet:

   if_stmt ::= "if" assignment_expression ":" suite
               ("elif" assignment_expression ":" suite)*
               ["else" ":" suite]

Es wählt genau eine der Suiten aus, indem es die Ausdrücke
nacheinander auswertet, bis einer als wahr erkannt wird (siehe
Abschnitt Boolesche Operationen für die Definition von "wahr"; und
"falsch".; anschließend wird diese Suite ausgeführt (und kein anderer
Teil der Anweisung "if" wird ausgeführt oder ausgewertet). Sind alle
Ausdrücke falsch, wird die Suite der Klausel "else" ausgeführt, sofern
vorhanden.


8.2. Die Erklärung der "while" .
================================

Die Anweisung "while" wird verwendet, um einen Befehl so lange
wiederholt auszuführen, wie ein Ausdruck wahr ist:

   while_stmt ::= "while" assignment_expression ":" suite
                  ["else" ":" suite]

Dadurch wird der Ausdruck wiederholt geprüft; ist er wahr, wird die
erste Suite ausgeführt; ist der Ausdruck falsch (was bereits bei der
ersten Prüfung der Fall sein kann), wird die Suite der Klausel "else"
. – sofern vorhanden – ausgeführt, und die Schleife wird beendet.

Eine in der ersten Suite ausgeführte Anweisung vom Typ "break" beendet
die Schleife, ohne die Suite der Klausel "else" auszuführen. Eine in
der ersten Suite ausgeführte Anweisung vom Typ "continue" überspringt
den Rest der Suite und kehrt zur Überprüfung des Ausdrucks zurück.


8.3. Die  "for" Anweisung
=========================

Die Anweisung "for" wird verwendet, um die Elemente einer Sequenz (wie
beispielsweise einer Zeichenkette, eines Tupels oder einer Liste) oder
eines anderen iterierbaren Objekts nacheinander durchzugehen:

   for_stmt ::= "for" target_list "in" `!starred_list` ":" suite
                ["else" ":" suite]

The "starred_list" expression is evaluated once; it should yield an
*iterable* object.  An *iterator* is created for that iterable. The
first item provided by the iterator is then assigned to the target
list using the standard rules for assignments (see
Zuweisungsanweisungen), and the suite is executed.  This repeats for
each item provided by the iterator.  When the iterator is exhausted,
the suite in the "else" clause, if present, is executed, and the loop
terminates.

Eine in der ersten Suite ausgeführte Anweisung "break" beendet die
Schleife, ohne die Suite der Klausel "else" auszuführen. Eine in der
ersten Suite ausgeführte Anweisung "continue" überspringt den Rest der
Suite und fährt mit dem nächsten Element fort oder, falls kein
nächstes Element vorhanden ist, mit der Klausel "else" .

Die for-Schleife führt Zuweisungen an die Variablen in der Zielliste
durch. Dadurch werden alle vorherigen Zuweisungen an diese Variablen
überschrieben, einschließlich derer, die im Rahmen der for-Schleife
vorgenommen wurden:

   for i in range(10):
       print(i)
       i = 5             # Dies hat keinen Einfluss auf die for-Schleife,
                         # da i durch den nächsten
                         # Index im Bereich überschrieben wird

Die Namen in der Zielliste werden nach Beendigung der Schleife nicht
gelöscht, aber wenn die Folge leer ist, wurden sie von der Schleife
gar nicht erst zugewiesen. Hinweis: Der integrierte Typ "range()"
stellt unveränderliche arithmetische Folgen von Ganzzahlen dar. Wenn
man beispielsweise nacheinander "range(3)" durchläuft, erhält man
nacheinander 0, 1 und dann 2.

Geändert in Version 3.11: Elemente mit Sternchen sind nun in der
Ausdrucksliste zulässig.


8.4. Die  "try" Anweisung
=========================

Die Anweisung "try" legt Ausnahmebehandler und/oder Aufräumcode für
eine Gruppe von Anweisungen fest:

   try_stmt  ::= try1_stmt | try2_stmt | try3_stmt
   try1_stmt ::= "try" ":" suite
                 ("except" [expression ["as" identifier]] ":" suite)+
                 ["else" ":" suite]
                 ["finally" ":" suite]
   try2_stmt ::= "try" ":" suite
                 ("except" "*" expression ["as" identifier] ":" suite)+
                 ["else" ":" suite]
                 ["finally" ":" suite]
   try3_stmt ::= "try" ":" suite
                 "finally" ":" suite

Weitere Informationen zu Ausnahmen finden Sie im Abschnitt Ausnahmen,
und Informationen zur Verwendung der Anweisung "raise" zum Auslösen
von Ausnahmen finden Sie im Abschnitt Die raise Anweisung .


8.4.1. "except" Klausel
-----------------------

Die Klausel(n) "except" legen einen oder mehrere Ausnahmebehandler
fest. Tritt in der Klausel "try" keine Ausnahme auf, wird kein
Ausnahmebehandler ausgeführt. Tritt in der Suite "try" eine Ausnahme
auf, wird eine Suche nach einem Ausnahmebehandler gestartet. Bei
dieser Suche werden die Klauseln "except" nacheinander durchgesehen,
bis eine gefunden wird, die der Ausnahme entspricht. Eine
ausdruckslose "except" -Klausel muss, sofern vorhanden, an letzter
Stelle stehen; sie passt auf jede Ausnahme.

For an "except" clause with an expression, the expression must
evaluate to an exception type or a tuple of exception types. The
raised exception matches an "except" clause whose expression evaluates
to the class or a *non-virtual base class* of the exception object, or
to a tuple that contains such a class.

Wenn keine "except" -Klausel mit der Ausnahme übereinstimmt, wird die
Suche nach einem Ausnahmehandler im umgebenden Code und auf dem
Aufrufstapel fortgesetzt. [1]

Wenn bei der Auswertung eines Ausdrucks im Kopf einer "except"
*-Klausel eine Ausnahme ausgelöst wird, wird die ursprüngliche Suche
nach einem Handler abgebrochen und es wird im umgebenden Code sowie
auf dem Aufrufstapel nach einem Handler für die neue Ausnahme gesucht
(es wird so behandelt, als hätte die gesamte :keyword:`try* -Anweisung
die Ausnahme ausgelöst).

Wird eine passende "except" -Klausel gefunden, wird die Ausnahme dem
Ziel zugewiesen, das nach dem Schlüsselwort "as" in dieser "except"
-Klausel angegeben ist, sofern vorhanden, und die Suite der "except"
-Klausel wird ausgeführt. Alle "except" -Klauseln müssen einen
ausführbaren Block enthalten. Wenn das Ende dieses Blocks erreicht
ist, wird die Ausführung nach der gesamten "try" -Anweisung normal
fortgesetzt. (Das bedeutet: Wenn zwei verschachtelte Handler für
dieselbe Ausnahme existieren und die Ausnahme in der "try" -Klausel
des inneren Handlers auftritt, wird die Ausnahme vom äußeren Handler
nicht behandelt.)

Wenn eine Ausnahme mit "as target" zugewiesen wurde, wird sie am Ende
der "except" -Klausel zurückgesetzt. Dies entspricht folgendem Code:

   except E as N:
       foo

wurde übersetzt in:

   except E as N:
       try:
           foo
       finally:
           del N

Das bedeutet, dass der Ausnahme ein anderer Name zugewiesen werden
muss, damit nach der "except" -Klausel auf sie verwiesen werden kann.
Ausnahmen werden gelöscht, da sie mit dem ihnen beigefügten Traceback
einen Referenzzyklus mit dem Stack-Frame bilden, wodurch alle lokalen
Variablen in diesem Frame so lange erhalten bleiben, bis die nächste
Garbage Collection stattfindet.

Bevor die Suite einer "except" -Klausel ausgeführt wird, wird die
Ausnahme im Modul "sys" gespeichert, wo im Körper der "except"
-Klausel durch den Aufruf von "sys.exception()" darauf zugegriffen
werden kann. Beim Verlassen eines Ausnahmebehandlers wird die im Modul
"sys" gespeicherte Ausnahme auf ihren vorherigen Wert zurückgesetzt:

   >>> print(sys.exception())
   None
   >>> try:
   ...     raise TypeError
   ... except:
   ...     print(repr(sys.exception()))
   ...     try:
   ...          raise ValueError
   ...     except:
   ...         print(repr(sys.exception()))
   ...     print(repr(sys.exception()))
   ...
   TypeError()
   ValueError()
   TypeError()
   >>> print(sys.exception())
   None


8.4.2. "except*" Klausel
------------------------

Die Klausel(n) "except*" legen einen oder mehrere Handler für Gruppen
von Ausnahmen (Instanzen von "BaseExceptionGroup") fest. Eine
Anweisung "try" kann entweder Klauseln vom Typ "except" oder "except*"
enthalten, jedoch nicht beide. Der Ausnahmetyp für den Abgleich ist im
Fall von "except*" obligatorisch, daher ist "except*:" ein
Syntaxfehler. Der Typ wird wie im Fall von "except" interpretiert, der
Abgleich erfolgt jedoch anhand der Ausnahmen, die in der gerade
behandelten Gruppe enthalten sind. Eine "TypeError" wird ausgelöst,
wenn ein übereinstimmender Typ eine Unterklasse von
"BaseExceptionGroup" ist, da dies zu einer mehrdeutigen Semantik
führen würde.

Wenn im "try"-Block eine Ausnahmegruppe ausgelöst wird, teilt jede
"except*" -Klausel (siehe "split()") diese in die Untergruppen der
passenden und der nicht passenden Ausnahmen auf. Ist die Untergruppe
der passenden Ausnahmen nicht leer, wird sie zur behandelten Ausnahme
(dem von "sys.exception()" zurückgegebenen Wert) und dem Ziel der
"except*" -Klausel zugewiesen (sofern vorhanden). Anschließend wird
der Hauptteil der Klausel "except*" ausgeführt. Ist die Untergruppe
der nicht übereinstimmenden Ausnahmen nicht leer, wird sie von der
nächsten Klausel "except*" auf dieselbe Weise verarbeitet. Dies wird
so lange fortgesetzt, bis alle Ausnahmen in der Gruppe abgeglichen
wurden oder die letzte Klausel "except*" ausgeführt wurde.

Nachdem alle "except*" -Klauseln ausgeführt wurden, wird die Gruppe
der nicht behandelten Ausnahmen mit allen Ausnahmen zusammengeführt,
die innerhalb von "except*" -Klauseln ausgelöst oder erneut ausgelöst
wurden. Diese zusammengeführte Ausnahmegruppe wird weitergegeben an:

   >>> try:
   ...     raise ExceptionGroup("eg",
   ...         [ValueError(1), TypeError(2), OSError(3), OSError(4)])
   ... except* TypeError as e:
   ...     print(f'caught {type(e)} with nested {e.exceptions}')
   ... except* OSError as e:
   ...     print(f'caught {type(e)} with nested {e.exceptions}')
   ...
   caught <class 'ExceptionGroup'> with nested (TypeError(2),)
   caught <class 'ExceptionGroup'> with nested (OSError(3), OSError(4))
     + Exception Group Traceback (most recent call last):
     |   File "<doctest default[0]>", line 2, in <module>
     |     raise ExceptionGroup("eg",
     |         [ValueError(1), TypeError(2), OSError(3), OSError(4)])
     | ExceptionGroup: eg (1 sub-exception)
     +-+---------------- 1 ----------------
       | ValueError: 1
       +------------------------------------

Wenn die im Block "try" ausgelöste Ausnahme keine Ausnahmegruppe ist
und ihr Typ mit einer der Klauseln "except*"  übereinstimmt, wird sie
abgefangen und von einer Ausnahmegruppe mit einer leeren
Meldungszeichenfolge umschlossen. Dadurch wird sichergestellt, dass
der Typ des Ziels "e" durchgehend "BaseExceptionGroup" lautet

   >>> try:
   ...     raise BlockingIOError
   ... except* BlockingIOError as e:
   ...     print(repr(e))
   ...
   ExceptionGroup('', (BlockingIOError(),))

"break", "continue" und "return" dürfen nicht in einer "except*"
-Klausel vorkommen.


8.4.3. "else" Klausel
---------------------

Die optionale Klausel "else" wird ausgeführt, wenn der Kontrollfluss
die Suite "try" verlässt, keine Ausnahme ausgelöst wurde und keine
Anweisung vom Typ "return", "continue" oder "break" ausgeführt wurde.
Ausnahmen in der Klausel "else" werden von den vorangehenden Klauseln
"except" nicht behandelt.


8.4.4. "finally" Klausel
------------------------

If "finally" is present, it specifies a 'cleanup' handler.  The "try"
clause is executed, including any "except" and "else" clauses. If an
exception occurs in any of the clauses and is not handled, the
exception is temporarily saved. The "finally" clause is executed.  If
there is a saved exception it is re-raised at the end of the "finally"
clause. If the "finally" clause raises another exception, the saved
exception is set as the context of the new exception. If the "finally"
clause executes a "return", "break" or "continue" statement, the saved
exception is discarded:

   >>> def f():
   ...     try:
   ...         1/0
   ...     finally:
   ...         return 42
   ...
   >>> f()
   42

Die Ausnahmedaten stehen dem Programm während der Ausführung der
Anweisung  "finally" nicht zur Verfügung.

Wenn eine Anweisung vom Typ "return", "break" oder "continue"
innerhalb der "try" -Suite einer Anweisung vom Typ "try"..."finally"
ausgeführt wird, wird die "finally" -Klausel ebenfalls "beim
Verlassen" ausgeführt.

The return value of a function is determined by the last "return"
statement executed.  Since the "finally" clause always executes, a
"return" statement executed in the "finally" clause will always be the
last one executed:

   >>> def foo():
   ...     try:
   ...         return 'try'
   ...     finally:
   ...         return 'finally'
   ...
   >>> foo()
   'finally'

Geändert in Version 3.8: Vor Python 3.8 war eine Anweisung vom Typ
"continue" in der Klausel "finally" aufgrund eines Problems bei der
Implementierung unzulässig.


8.5. Die Erklärung von "with" .
===============================

Die Anweisung "with" dient dazu, die Ausführung eines Blocks mit
Methoden zu umschließen, die von einem Kontextmanager definiert wurden
(siehe Abschnitt Mit Statement-Kontextmanagern). Dadurch lassen sich
gängige Verwendungsmuster wie "try"..."except"..."finally" zur
bequemen Wiederverwendung kapseln.

   with_stmt          ::= "with" ( "(" with_stmt_contents ","? ")" | with_stmt_contents ) ":" suite
   with_stmt_contents ::= with_item ("," with_item)*
   with_item          ::= expression ["as" target]

Die Ausführung der Anweisung "with" mit einem "Element" verläuft wie
folgt:

1. Der Kontextausdruck (der in der Datei "with_item"  angegebene
   Ausdruck) wird ausgewertet, um einen Kontextmanager zu erhalten.

2. Die "__enter__()" des Kontextmanagers wird zur späteren Verwendung
   geladen.

3. Die "__exit__()" des Kontextmanagers wird für die spätere
   Verwendung geladen.

4. Die Methode "__enter__()" des Kontextmanagers wird aufgerufen.

5. Wenn in der Anweisung "with" ein Ziel angegeben wurde, wird ihm der
   Rückgabewert von "__enter__()" zugewiesen.

   Bemerkung:

     Die "with"-Anweisung garantiert, dass "__exit__()" stets
     aufgerufen wird, sofern die Methode "__enter__()" fehlerfrei
     zurückkehrt. Tritt also während der Zuweisung an die Ziel-Liste
     ein Fehler auf, so wird dieser genauso behandelt wie ein Fehler
     innerhalb des Anweisungsblocks. Siehe Schritt 7 weiter unten.

6. Die Suite wurde aufgeführt.

7. Die Methode "__exit__()" des Kontextmanagers wird aufgerufen. Wenn
   eine Ausnahme zum Abbruch der Suite geführt hat, werden deren Typ,
   Wert und Traceback als Argumente an "__exit__()" übergeben.
   Andernfalls werden drei Argumente vom Typ "None" übergeben.

   Wurde die Suite aufgrund einer Ausnahme beendet und war der
   Rückgabewert der Methode "__exit__()" *false*, wird die Ausnahme
   erneut ausgelöst. War der Rückgabewert *true*, wird die Ausnahme
   unterdrückt, und die Ausführung wird mit der Anweisung fortgesetzt,
   die auf die Anweisung "with" folgt.

   Wurde die Suite aus einem anderen Grund als einer Ausnahme beendet,
   wird der Rückgabewert von "__exit__()" ignoriert, und die
   Ausführung wird an der für die jeweilige Beendigungsart üblichen
   Stelle fortgesetzt.

Der folgende Code:

   with EXPRESSION as TARGET:
       SUITE

ist semantisch gleichbedeutend mit:

   manager = (EXPRESSION)
   enter = manager.__enter__
   exit = manager.__exit__
   value = enter()
   hit_except = False

   try:
       TARGET = value
       SUITE
   except:
       hit_except = True
       if not exit(*sys.exc_info()):
           raise
   finally:
       if not hit_except:
           exit(None, None, None)

mit der Ausnahme, dass für "__enter__()" und "__exit__()" die
implizite Spezialmethoden-Suche verwendet wird.

Bei mehr als einem Element werden die Kontextmanager so verarbeitet,
als wären mehrere "with" -Anweisungen verschachtelt:

   with A() as a, B() as b:
       SUITE

ist semantisch gleichbedeutend mit:

   with A() as a:
       with B() as b:
           SUITE

Sie können Kontextmanager mit mehreren Elementen auch über mehrere
Zeilen hinweg schreiben, wenn die Elemente in Klammern stehen. Zum
Beispiel:

   with (
       A() as a,
       B() as b,
   ):
       SUITE

Geändert in Version 3.1: Unterstützung für mehrere Kontext-Ausdrücke.

Geändert in Version 3.10: Unterstützung für die Verwendung von
Gruppierungsklammern, um die Anweisung auf mehrere Zeilen aufzuteilen.

Siehe auch:

  **PEP 343** - Die "with"-Anweisung
     Die Spezifikation, Hintergrundinformationen und Beispiele zur
     Python-Anweisung "with" .


8.6. Die Erklärung der "match" Anweisung
========================================

Added in version 3.10.

Die "match"-Anweisung dient zum Musterabgleich. Syntax:

   match_stmt   ::= 'match' subject_expr ":" NEWLINE INDENT case_block+ DEDENT
   subject_expr ::= flexible_expression "," [flexible_expression_list [',']]
                    | assignment_expression
   case_block   ::= 'case' patterns [guard] ":" suite

Bemerkung:

  In diesem Abschnitt werden einfache Anführungszeichen verwendet, um
  Soft-Schlüsselwörter zu kennzeichnen.

Beim Musterabgleich werden ein Muster als Eingabe (gemäß "case") und
ein Zielwert (gemäß "match") verwendet. Das Muster (das Untermuster
enthalten kann) wird mit dem Zielwert abgeglichen. Die möglichen
Ergebnisse sind:

* Ein Übereinstimmungserfolg oder -misserfolg (auch als Mustererfolg
  oder -misserfolg bezeichnet).

* Mögliche Zuordnung übereinstimmender Werte zu einem Namen. Die
  Voraussetzungen hierfür werden im Folgenden näher erläutert.

Die Schlüsselwörter "match" und "case" sind Soft-Schlüsselwörter.

Siehe auch:

  * **PEP 634** -- Struktureller Musterabgleich: Spezifikation

  * **PEP 636** -- Struktureller Musterabgleich: Tutorial


8.6.1. Übersicht
----------------

Hier ist ein Überblick über den logischen Ablauf einer
"match"-Anweisung:

1. Der Subjekt-Ausdruck "subject_expr" wird ausgewertet und der
   resultierende Subjektwert ermittelt. Enthält der Subjekt-Ausdruck
   ein Komma, wird ein Tupel gemäß den Standardregeln gebildet.

2. Jedes Muster in einem "case_block" wird mit dem entsprechenden Wert
   abgeglichen. Die konkreten Regeln für Erfolg oder Misserfolg werden
   im Folgenden beschrieben. Der Abgleichversuch kann auch einige oder
   alle eigenständigen Namen innerhalb des Musters binden. Die genauen
   Regeln für die Musterbindung variieren je nach Mustertyp und werden
   im Folgenden näher erläutert.  **Namensbindungen, die während eines
   erfolgreichen Musterabgleichs vorgenommen werden, bestehen über den
   ausgeführten Block hinaus fort und können nach der
   `match`-Anweisung verwendet werden**.

   Bemerkung:

     Bei fehlgeschlagenen Musterabgleichen können einige Teilmuster
     erfolgreich sein. Verlassen Sie sich nicht darauf, dass bei einem
     fehlgeschlagenen Abgleich Bindungen hergestellt werden. Verlassen
     Sie sich umgekehrt auch nicht darauf, dass Variablen nach einem
     fehlgeschlagenen Abgleich unverändert bleiben. Das genaue
     Verhalten hängt von der Implementierung ab und kann variieren.
     Dies ist eine bewusste Entscheidung, die getroffen wurde, um
     verschiedenen Implementierungen die Möglichkeit zu geben,
     Optimierungen hinzuzufügen.

3. Wenn das Muster erfolgreich ist, wird die entsprechende Bedingung
   (sofern vorhanden) ausgewertet. In diesem Fall ist gewährleistet,
   dass alle Namenszuordnungen bereits erfolgt sind.

   * Wenn die Bedingung wahr ist oder fehlt, wird die Anweisung
     "block" innerhalb von "case_block" ausgeführt.

   * Andernfalls wird, wie oben beschrieben, der nächste "case_block"
     versucht.

   * Wenn keine weiteren Fallblöcke mehr vorhanden sind, ist die
     "match"-Anweisung abgeschlossen.

Bemerkung:

  Benutzer sollten sich grundsätzlich nie darauf verlassen, dass ein
  Muster ausgewertet wird. Je nach Implementierung speichert der
  Interpreter Werte möglicherweise im Cache oder nutzt andere
  Optimierungen, durch die wiederholte Auswertungen übersprungen
  werden.

Ein Beispiel für eine Abgleichsanweisung:

   >>> flag = False
   >>> match (100, 200):
   ...    case (100, 300):  # Keine Übereinstimmung: 200 ≠ 300
   ...        print('Fall 1')
   ...    case (100, 200) if flag:  # Übereinstimmung erfolgreich, aber Bedingung nicht erfüllt
   ...        print('Fall 2')
   ...    case (100, y):  # Übereinstimmung und y wird auf 200 gesetzt
   ...        print(f'Fall 3, y: {y}')
   ...    case _:  # Muster wird nicht versucht
   ...        print('Fall 4, ich passe auf alles!')
   ...
   Fall 3, y: 200

In diesem Fall ist "if flag" ein Guard. Mehr dazu erfahren Sie im
nächsten Abschnitt.


8.6.2. Guards
-------------

   guard ::= "if" assignment_expression

Ein "guard" (der Teil des "case" ist) muss erfolgreich sein, damit der
Code innerhalb des "case" -Blocks ausgeführt wird. Er hat folgende
Form: "if", gefolgt von einem Ausdruck.

Der logische Ablauf eines "case" -Blocks mit einem "guard" sieht wie
folgt aus:

1. Überprüfen Sie, ob die Musterprüfung im Block "case" erfolgreich
   war. Falls die Musterprüfung fehlgeschlagen ist, wird der Block
   "guard" nicht ausgewertet und der nächste Block "case" geprüft.

2. Wenn die Mustererkennung erfolgreich war, werte die "guard" aus.

   * Wenn die Bedingung "guard" als wahr ausgewertet wird, wird der
     "case"-Block ausgewählt.

   * Wenn die Bedingung "guard" als "falsch" ausgewertet wird, wird
     der "case"-Block nicht ausgewählt.

   * Wenn die "guard" während der Auswertung eine Ausnahme auslöst,
     wird diese nach oben weitergeleitet.

Guards dürfen Nebenwirkungen haben, da es sich um Ausdrücke handelt.
Die Auswertung der Guards muss vom ersten bis zum letzten Case-Block
nacheinander erfolgen, wobei Case-Blöcke übersprungen werden, deren
Muster nicht alle erfolgreich sind. (Das heißt, die Auswertung der
Guards muss in der richtigen Reihenfolge erfolgen.) Die Auswertung der
Guards muss beendet werden, sobald ein Case-Block ausgewählt wurde.


8.6.3. Unwiderlegbare Argumente
-------------------------------

Ein unwiderlegbarer Fallblock ist ein Fallblock, der alle Fälle
abdeckt. Eine *match*-Anweisung darf höchstens einen unwiderlegbaren
Fallblock enthalten, und dieser muss an letzter Stelle stehen.

Ein Fallblock gilt als unwiderlegbar, wenn er keine Schutzklausel
enthält und sein Muster unwiderlegbar ist. Ein Muster gilt als
unwiderlegbar, wenn sich allein anhand seiner Syntax nachweisen lässt,
dass es immer erfolgreich ist. Nur die folgenden Muster sind
unwiderlegbar:

* AS-Muster dessen linke Seite unwiderlegbar ist

* ODER ("Oder") Muster das mindestens ein unwiderlegbares Muster
  enthält

* Erfassungsmuster / Capture-Muster

* Platzhaltermuster

* in Klammern gesetzte, unwiderlegbare Muster


8.6.4. Muster
-------------

Bemerkung:

  In diesem Abschnitt werden Grammatiknotationen verwendet, die über
  die Standard-EBNF hinausgehen:

  * Die Schreibweise "SEP.RULE+" ist eine Kurzschreibweise für "RULE
    (SEP RULE)*"

  * Die Schreibweise "!RULE" ist eine Kurzform für eine negative
    Lookahead-Bedingung.

Die übergeordnete Syntax für "patterns" lautet:

   patterns       ::= open_sequence_pattern | pattern
   pattern        ::= as_pattern | or_pattern
   closed_pattern ::= | literal_pattern
                      | capture_pattern
                      | wildcard_pattern
                      | value_pattern
                      | group_pattern
                      | sequence_pattern
                      | mapping_pattern
                      | class_pattern

Die folgenden Beschreibungen enthalten zur Veranschaulichung eine
"einfach formulierte"; Erläuterung der Funktionsweise eines Musters
(Dank gilt Raymond Hettinger für ein Dokument, das als Vorlage für die
meisten dieser Beschreibungen diente). Bitte beachten Sie, dass diese
Beschreibungen rein zur Veranschaulichung dienen und **möglicherweise
nicht** die zugrunde liegende Implementierung widerspiegeln. Außerdem
decken sie nicht alle gültigen Formen ab.


8.6.4.1. ODER ("Oder") Muster
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Ein OR-Muster besteht aus zwei oder mehr Mustern, die durch senkrechte
Striche getrennt sind: "|".  Syntax:

   or_pattern ::= "|".closed_pattern+

Nur das letzte Teilmuster darf irrefutable sein, und jedes Teilmuster
muss dieselbe Menge von Namen binden, um Mehrdeutigkeiten zu
vermeiden.

Ein OR-Muster gleicht nacheinander jedes seiner Teilmuster mit dem
Suchwert ab, bis eines davon übereinstimmt. Das OR-Muster gilt dann
als erfolgreich. Andernfalls, wenn keines der Teilmuster
übereinstimmt, schlägt das OR-Muster fehl.

Einfach ausgedrückt: "P1 | P2 | ..." versucht zunächst, "P1"
abzugleichen; sollte dies fehlschlagen, wird "P2" versucht. Sobald
einer der Versuche erfolgreich ist, ist der Vorgang abgeschlossen;
andernfalls schlägt er fehl.


8.6.4.2. AS-Muster
~~~~~~~~~~~~~~~~~~

Ein "AS"-Muster gleicht ein "OR"-Muster links vom Schlüsselwort "as"
mit einem Subjekt ab.  Syntax:

   as_pattern ::= or_pattern "as" capture_pattern

Wenn das OR-Muster fehlschlägt, schlägt auch das AS-Muster fehl.
Andernfalls bindet das AS-Muster das Subjekt an den Namen rechts vom
Schlüsselwort "as". und ist erfolgreich. "capture_pattern" darf kein
"_" sein.

Einfach ausgedrückt: "P as NAME" wird mit "P" abgeglichen, und bei
Erfolg wird "NAME = <subject>" gesetzt.


8.6.4.3. Literale Muster
~~~~~~~~~~~~~~~~~~~~~~~~

Ein Literalmuster entspricht den meisten Literalen in Python.  Syntax:

   literal_pattern ::= signed_number
                       | signed_number "+" NUMBER
                       | signed_number "-" NUMBER
                       | `!strings`
                       | "None"
                       | "True"
                       | "False"
   signed_number   ::= ["-"] NUMBER

The rule "strings" and the token "NUMBER" are defined in the standard
Python grammar.  Triple-quoted strings are supported.  Raw strings and
byte strings are supported.  f-Strings are not supported.

Die Formate "signed_number '+' NUMBER" und "signed_number '-' NUMBER"
dienen zur Darstellung von komplexen Zahlen; sie erfordern links eine
reelle Zahl und rechts eine imaginäre Zahl. Beispiel: "3 + 4j".

Einfach ausgedrückt: "LITERAL" ist nur dann erfolgreich, wenn
"<subject> == LITERAL" . Für die einmaligen Objekte (Singleton)
"None", "True" und "False" wird der Operator "is" verwendet.


8.6.4.4. Erfassungsmuster / Capture-Muster
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Ein Capture-Muster ordnet den Wert des Subjekts einem Namen zu.
Syntax:

   capture_pattern ::= !'_' NAME

Ein einzelner Unterstrich "_" ist kein Capture-Muster (dies wird durch
"!'_'" ausgedrückt). Er wird stattdessen als "wildcard_pattern"
behandelt.

In einem bestimmten Muster kann ein bestimmter Name nur einmal
verwendet werden. Beispielsweise ist "case x, x: ..." ungültig,
während "case [x] | x: ..." zulässig ist.

Capture-Muster sind immer erfolgreich. Die Bindung folgt den Regeln
für den Gültigkeitsbereich, die durch den Zuweisungsausdrucksoperator
in **PEP 572** festgelegt sind; der Name wird zu einer lokalen
Variablen im nächstgelegenen übergeordneten
Funktionsgültigkeitsbereich, sofern keine entsprechende Anweisung vom
Typ "global" oder "nonlocal" vorliegt.

Einfach ausgedrückt: "NAME" wird immer erfolgreich sein und "NAME =
<subject>" setzen.


8.6.4.5. Platzhaltermuster
~~~~~~~~~~~~~~~~~~~~~~~~~~

Ein Platzhaltermuster ist immer erfolgreich (passt auf alles) und
bindet keinen Namen. Syntax:

   wildcard_pattern ::= '_'

"_" ist ein Soft-Schlüsselwort innerhalb beliebiger Muster, jedoch
ausschließlich innerhalb von Mustern. Es handelt sich wie üblich um
einen Bezeichner, selbst innerhalb von "match" Subjekt-Ausdrücken,
"guard"s und "case" Blöcken.

Einfach ausgedrückt: "_" wird immer erfolgreich sein.


8.6.4.6. Wertmuster
~~~~~~~~~~~~~~~~~~~

Ein Wertmuster repräsentiert einen benannten Wert in Python. Syntax:

   value_pattern ::= attr
   attr          ::= name_or_attr "." NAME
   name_or_attr  ::= attr | NAME

Der mit einem Punkt gekennzeichnete Name im Muster wird anhand der
Standardregeln für die Namensauflösung in Python nachgeschlagen:
:ref:` <resolve_names>`. Das Muster ist erfolgreich, wenn der
gefundene Wert mit dem Suchwert übereinstimmt (unter Verwendung des
Gleichheitsoperators "==" ).

Einfach ausgedrückt: "NAME1.NAME2" wird nur dann erfolgreich sein,
wenn "<subject> == NAME1.NAME2"

Bemerkung:

  Wenn derselbe Wert mehrmals in derselben "match"-Anweisung vorkommt,
  kann der Interpreter den zuerst gefundenen Wert zwischenspeichern
  und wiederverwenden, anstatt die Suche erneut durchzuführen. Dieser
  Zwischenspeicher ist streng an eine bestimmte Ausführung einer
  bestimmten "match"-Anweisung gebunden.


8.6.4.7. Gruppenmuster
~~~~~~~~~~~~~~~~~~~~~~

Ein Gruppenmuster ermöglicht es Benutzern, Muster in Klammern zu
setzen, um die beabsichtigte Gruppierung hervorzuheben. Ansonsten gibt
es keine zusätzliche Syntax. Syntax:

   group_pattern ::= "(" pattern ")"

Einfach ausgedrückt hat "(P)" dieselbe Wirkung wie "P" .


8.6.4.8. Sequenzmuster
~~~~~~~~~~~~~~~~~~~~~~

Ein Sequenzmuster enthält mehrere Untermuster, die mit
Sequenzelementen abgeglichen werden sollen. Die Syntax ähnelt dem
Entpacken einer Liste oder eines Tupels.

   sequence_pattern       ::= "[" [maybe_sequence_pattern] "]"
                              | "(" [open_sequence_pattern] ")"
   open_sequence_pattern  ::= maybe_star_pattern "," [maybe_sequence_pattern]
   maybe_sequence_pattern ::= ",".maybe_star_pattern+ ","?
   maybe_star_pattern     ::= star_pattern | pattern
   star_pattern           ::= "*" (capture_pattern | wildcard_pattern)

Es spielt keine Rolle, ob für Sequenzmuster runde Klammern oder eckige
Klammern verwendet werden (d. h. "(...)" vs. "[...]" ).

Bemerkung:

  Ein einzelnes Muster in runden Klammern ohne abschließendes Komma
  (z. B. "(3 | 4)") ist ein Gruppenmuster. Ein einzelnes Muster in
  eckigen Klammern (z. B. "[3 | 4]") ist hingegen weiterhin ein
  Sequenzmuster.

Ein Sequenzmuster darf höchstens ein Stern-Teilmuster enthalten. Das
Stern-Teilmuster kann an beliebiger Stelle vorkommen. Ist kein Stern-
Teilmuster vorhanden, handelt es sich um ein Sequenzmuster fester
Länge; andernfalls handelt es sich um ein Sequenzmuster variabler
Länge.

Im Folgenden wird der logische Ablauf beim Abgleich eines
Sequenzmusters mit einem Zielwert beschrieben:

1. Ist der Wert des Subjekts keine Sequenz [2], schlägt das
   Sequenzmuster fehl.

2. Wenn der Wert des Subjekts eine Instanz von "str", "bytes" oder
   "bytearray" ist, schlägt das Sequenzmuster fehl.

3. Die weiteren Schritte hängen davon ab, ob das Sequenzmuster eine
   feste oder eine variable Länge hat.

   Wenn das Sequenzmuster eine feste Länge hat:

   1. Wenn die Länge der zu prüfenden Sequenz nicht mit der Anzahl der
      Teilmuster übereinstimmt, schlägt die Sequenzprüfung fehl.

   2. Teilmuster im Sequenzmuster werden von links nach rechts mit den
      entsprechenden Elementen in der zu prüfenden Sequenz
      abgeglichen. Der Abgleich wird beendet, sobald ein Teilmuster
      nicht übereinstimmt. Wenn alle Teilmuster erfolgreich mit den
      entsprechenden Elementen abgeglichen werden, gilt das
      Sequenzmuster als erfolgreich.

   Andernfalls, wenn das Sequenzmuster eine variable Länge hat:

   1. Ist die Länge der zu prüfenden Sequenz kürzer als die Anzahl der
      Nicht-Stern-Teilmuster, gilt das Sequenzmuster als nicht
      erfüllt.

   2. Die führenden Teilmuster ohne Sternzeichen werden wie bei
      Sequenzen fester Länge ihren entsprechenden Elementen
      zugeordnet.

   3. Wenn der vorherige Schritt erfolgreich ist, passt das Stern-
      Teilmuster auf eine Liste, die aus den verbleibenden
      Suchbegriffen gebildet wird, wobei die verbleibenden Begriffe,
      die Nicht-Stern-Teilmuster im Anschluss an das Stern-Teilmuster
      entsprechen, ausgeschlossen werden.

   4. Die verbleibenden Teilmuster ohne Stern werden wie bei einer
      Sequenz fester Länge ihren entsprechenden Subjektelementen
      zugeordnet.

   Bemerkung:

     Die Länge der Objektsequenz wird über "len()" ermittelt (d. h.
     über das "__len__()" Protokoll ). Diese Länge kann vom
     Interpreter auf ähnliche Weise wie Wertmuster zwischengespeichert
     werden.

Einfach ausgedrückt: "[P1, P2, P3,"... ", P<N>]" ergibt nur dann eine
Übereinstimmung, wenn alle folgenden Bedingungen erfüllt sind:

* Überprüfe, ob "<subject>" eine Folge ist

* "len(subject) == <N>"

* "P1" entspricht "<subject>[0]" (beachte, dass diese Übereinstimmung
  auch Namen binden kann)

* "P2" entspricht "<subject>[1]" (beachte, dass diese Übereinstimmung
  auch Namen binden kann)

* ... und so weiter für das jeweilige Muster bzw. Element.


8.6.4.9. Zuordnungsmuster
~~~~~~~~~~~~~~~~~~~~~~~~~

Ein Zuordnungsmuster enthält ein oder mehrere Schlüssel-Wert-Muster.
Die Syntax ähnelt dem Aufbau eines Wörterbuchs. Syntax:

   mapping_pattern     ::= "{" [items_pattern] "}"
   items_pattern       ::= ",".key_value_pattern+ ","?
   key_value_pattern   ::= (literal_pattern | value_pattern) ":" pattern
                           | double_star_pattern
   double_star_pattern ::= "**" capture_pattern

Ein Zuordnungsmuster darf höchstens ein Doppelsternmuster enthalten.
Das Doppelsternmuster muss das letzte Teilmuster im Zuordnungsmuster
sein.

Doppelte Schlüssel in Zuordnungsmustern sind nicht zulässig. Doppelte
Literalschlüssel lösen eine "SyntaxError" aus. Zwei Schlüssel, die
ansonsten denselben Wert haben, lösen zur Laufzeit eine "ValueError"
aus.

Im Folgenden wird der logische Ablauf beim Abgleich eines
Zuordnungsmusters mit einem Objektwert beschrieben:

1. Wenn der Wert des Subjekts kein Zuordnungs [3] ist, schlägt das
   Zuordnungsmuster fehl.

2. Wenn jeder im Zuordnungsmuster angegebene Schlüssel in der
   Zielzuordnung vorhanden ist und das Muster für jeden Schlüssel mit
   dem entsprechenden Eintrag in der Zielzuordnung übereinstimmt, ist
   das Zuordnungsmuster erfolgreich.

3. Werden im Zuordnungsmuster doppelte Schlüssel erkannt, gilt das
   Muster als ungültig. Bei doppelten Literalwerten wird eine
   "SyntaxError" ausgelöst; bei benannten Schlüsseln mit identischem
   Wert eine "ValueError" .

Bemerkung:

  Schlüssel-Wert-Paare werden mithilfe der Zwei-Argument-Form der
  Methode "get()" des Mapping-Objekts abgeglichen. Die abgeglichenen
  Schlüssel-Wert-Paare müssen bereits im Mapping vorhanden sein und
  dürfen nicht dynamisch über "__missing__()" oder "__getitem__()"
  erstellt werden.

Einfach ausgedrückt: "{KEY1: P1, KEY2: P2, ... }" ergibt nur dann eine
Übereinstimmung, wenn alle folgenden Bedingungen erfüllt sind:

* Schau mal unter "<subject>" nach – dort findest du eine Karte.

* "KEY1 in <subject>"

* "P1" stimmt mit "<subject>[KEY1]" überein.

* ... und so weiter für das jeweilige Schlüssel-Muster-Paar.


8.6.4.10. Klassenmuster
~~~~~~~~~~~~~~~~~~~~~~~

Ein Klassenmuster repräsentiert eine Klasse sowie deren Positions- und
Schlüsselwortargumente (sofern vorhanden).  Syntax:

   class_pattern       ::= name_or_attr "(" [pattern_arguments ","?] ")"
   pattern_arguments   ::= positional_patterns ["," keyword_patterns]
                           | keyword_patterns
   positional_patterns ::= ",".pattern+
   keyword_patterns    ::= ",".keyword_pattern+
   keyword_pattern     ::= NAME "=" pattern

Dasselbe Schlüsselwort sollte in Klassenmustern nicht wiederholt
werden.

Im Folgenden wird der logische Ablauf beim Abgleich eines
Klassenmusters mit einem Subjektwert beschrieben:

1. Wenn "name_or_attr" keine Instanz der integrierten Klasse "type"
   ist, wird ein "TypeError" ausgelöst.

2. Wenn der Wert des Subjekts keine Instanz von "name_or_attr" ist
   (geprüft über "isinstance()") , schlägt das Klassenmuster fehl.

3. Sind keine Musterargumente vorhanden, ist die Musterprüfung
   erfolgreich. Andernfalls hängen die nachfolgenden Schritte davon
   ab, ob Muster für Schlüsselwort- oder Positionsargumente vorhanden
   sind.

   Bei einer Reihe von integrierten Typen (siehe unten) wird ein
   einzelnes positionelles Teilmuster akzeptiert, das mit dem gesamten
   Subjekt übereinstimmt; bei diesen Typen funktionieren
   Schlüsselwortmuster ebenso wie bei anderen Typen.

   Sind nur Schlüsselwortmuster vorhanden, werden diese nacheinander
   wie folgt verarbeitet:

   1. Das Schlüsselwort wird als Attribut des Subjekts nachgeschlagen.

      * Wenn dabei eine andere Ausnahme als "AttributeError" ausgelöst
        wird, wird die Ausnahme weitergeleitet.

      * Wenn dabei ein "AttributeError" ausgelöst wird, ist das
        Klassenmuster fehlgeschlagen.

      * Andernfalls wird das mit dem Schlüsselwortmuster verknüpfte
        Teilmuster mit dem Attributwert des Subjekts abgeglichen.
        Gelingt dies nicht, schlägt das Klassenmuster fehl; gelingt
        es, wird der Abgleich mit dem nächsten Schlüsselwort
        fortgesetzt.

   2. Wenn alle Schlüsselwortmuster erfolgreich sind, ist das
      Klassenmuster erfolgreich.

   Falls Positionsmuster vorhanden sind, werden diese vor dem Abgleich
   mithilfe des Attributs "__match_args__" der Klasse "name_or_attr"
   in Schlüsselwortmuster umgewandelt:

   1. Es wird das Äquivalent von "getattr(cls, "__match_args__", ())"
      aufgerufen.

      * Wenn dabei eine Ausnahme ausgelöst wird, wird diese nach oben
        weitergeleitet.

      * Wenn der Rückgabewert kein Tupel ist, schlägt die
        Konvertierung fehl und es wird ein "TypeError" -Fehler
        ausgelöst.

      * Wenn es mehr Positionsmuster gibt als
        "len(cls.__match_args__)", wird "TypeError" ausgelöst.

      * Andernfalls wird das Positionsmuster "i" mithilfe von
        "__match_args__[i]" als Schlüsselwort in ein
        Schlüsselwortmuster umgewandelt. "__match_args__[i]" muss eine
        Zeichenkette sein; andernfalls wird "TypeError" ausgelöst.

      * Wenn doppelte Schlüsselwörter vorhanden sind, wird ein
        "TypeError" ausgelöst.

      Siehe auch:

        Anpassen von Positionsargumenten beim Klassenmusterabgleich

   2. Sobald alle Positionsmuster in Schlüsselwortmuster umgewandelt
      wurden, verläuft die Suche so, als gäbe es nur
      Schlüsselwortmuster.

   Bei den folgenden integrierten Typen unterscheidet sich die
   Behandlung von Positionsuntermustern:

   * "bool"

   * "bytearray"

   * "bytes"

   * "dict"

   * "float"

   * "frozenset"

   * "int"

   * "list"

   * "set"

   * "str"

   * "tuple"

   Diese Klassen akzeptieren ein einzelnes positionsbezogenes
   Argument, und das Muster wird dabei mit dem gesamten Objekt
   abgeglichen und nicht mit einem Attribut. Beispielsweise passt
   "int(0|1)" auf den Wert "0", nicht jedoch auf den Wert "0.0" .

Einfach ausgedrückt passt "CLS(P1, attr=P2)" nur dann, wenn Folgendes
zutrifft:

* "isinstance(<subject>, CLS)"

* "P1" mithilfe von "CLS.__match_args__" in ein Schlüsselwortmuster
  umwandeln

* Für jedes Schlüsselwortargument "attr=P2":

  * "hasattr(<subject>, "attr")"

  * "P2" stimmt mit "<subject>.attr" überein

* ... und so weiter für das entsprechende Schlüsselwort-Argument-
  Muster-Paar.

Siehe auch:

  * **PEP 634** -- Struktureller Musterabgleich: Spezifikation

  * **PEP 636** -- Struktureller Musterabgleich: Tutorial


8.7. Funktionsdefinitionen
==========================

Eine Funktionsdefinition definiert ein benutzerdefiniertes
Funktionsobjekt (siehe Abschnitt Die Standardtyp-Hierarchie):

   funcdef                   ::= [decorators] "def" funcname [type_params] "(" [parameter_list] ")"
                                 ["->" expression] ":" suite
   decorators                ::= decorator+
   decorator                 ::= "@" assignment_expression NEWLINE
   parameter_list            ::= defparameter ("," defparameter)* "," "/" ["," [parameter_list_no_posonly]]
                                 | parameter_list_no_posonly
   parameter_list_no_posonly ::= defparameter ("," defparameter)* ["," [parameter_list_starargs]]
                                 | parameter_list_starargs
   parameter_list_starargs   ::= "*" star_parameter ("," defparameter)* ["," [parameter_star_kwargs]]
                                 | "*" ("," defparameter)+ ["," [parameter_star_kwargs]]
                                 | parameter_star_kwargs
   parameter_star_kwargs     ::= "**" parameter [","]
   parameter                 ::= identifier [":" expression]
   star_parameter            ::= identifier [":" ["*"] expression]
   defparameter              ::= parameter ["=" expression]
   funcname                  ::= identifier

Eine Funktionsdefinition ist eine ausführbare Anweisung. Durch ihre
Ausführung wird der Funktionsname im aktuellen lokalen Namensraum an
ein Funktionsobjekt gebunden (eine Hülle um den ausführbaren Code der
Funktion). Dieses Funktionsobjekt enthält einen Verweis auf den
aktuellen globalen Namensraum als den globalen Namensraum, der beim
Aufruf der Funktion verwendet werden soll.

Bei der Funktionsdefinition wird der Funktionskörper nicht ausgeführt;
dieser wird erst ausgeführt, wenn die Funktion aufgerufen wird. [4]

Eine Funktionsdefinition kann von einem oder mehreren
*Decorator*-Ausdrücken umschlossen sein. Decorator-Ausdrücke werden
bei der Definition der Funktion in dem Geltungsbereich ausgewertet,
der die Funktionsdefinition enthält. Das Ergebnis muss ein aufrufbares
Objekt sein, das mit dem Funktionsobjekt als einzigem Argument
aufgerufen wird. Der zurückgegebene Wert wird an den Funktionsnamen
statt an das Funktionsobjekt gebunden.  Mehrere Dekoratoren werden
verschachtelt angewendet. Beispielsweise der folgende Code

   @f1(arg)
   @f2
   def func(): pass

entspricht in etwa

   def func(): pass
   func = f1(arg)(f2(func))

außer dass die ursprüngliche Funktion nicht vorübergehend an den Namen
"func" gebunden ist.

Geändert in Version 3.9: Funktionen können mit jedem gültigen
"assignment_expression" versehen werden. Früher war die Syntax
wesentlich restriktiver; weitere Informationen finden Sie unter **PEP
614**.

Eine Liste von Typ-Parametern kann in eckigen Klammern zwischen dem
Namen der Funktion und der öffnenden Klammer für ihre Parameterliste
angegeben werden. Dies signalisiert statischen Typprüfern, dass es
sich um eine generische Funktion handelt. Zur Laufzeit können die Typ-
Parameter über das Attribut "__type_params__" der Funktion abgerufen
werden. Weitere Informationen finden Sie unter Generische Funktionen.

Geändert in Version 3.12: Typ-Parameterlisten sind eine Neuerung in
Python 3.12.

Wenn ein oder mehrere *Parameter* die Form *Parameter* "=" *Ausdruck*
haben, spricht man davon, dass die Funktion "Standardparameterwerte";
besitzt. Bei einem Parameter mit einem Standardwert kann das
entsprechende *Argument* bei einem Aufruf weggelassen werden; in
diesem Fall wird der Standardwert des Parameters eingesetzt.  Wenn ein
Parameter einen Standardwert hat, müssen auch alle nachfolgenden
Parameter bis zum "*" einen Standardwert haben – dies ist eine
syntaktische Einschränkung, die in der Grammatik nicht ausdrücklich
erwähnt wird.

**Standardparameterwerte werden bei der Ausführung der
Funktionsdefinition von links nach rechts ausgewertet.** Das bedeutet,
dass der Ausdruck einmalig bei der Definition der Funktion ausgewertet
wird und dass bei jedem Aufruf derselbe "vorberechnete" Wert verwendet
wird.  Dies ist besonders wichtig zu verstehen, wenn ein
Standardparameterwert ein veränderliches Objekt ist, wie
beispielsweise eine Liste oder ein Wörterbuch: Wenn die Funktion das
Objekt verändert (z. B. durch Anhängen eines Elements an eine Liste),
wird der Standardparameterwert faktisch verändert. Dies ist in der
Regel nicht beabsichtigt.  Eine Möglichkeit, dies zu umgehen, besteht
darin, "None" als Standardwert zu verwenden und im Funktionskörper
explizit darauf zu prüfen, zum Beispiel:

   def was_läuft_im_Fernseher(Pinguin=None):
       if Pinguin is None:
           Pinguin = []
       Pinguin.append("Eigentum des Zoos")
       return Pinguin

Die Semantik von Funktionsaufrufen wird im Abschnitt Calls näher
beschrieben. Ein Funktionsaufruf weist allen in der Parameterliste
genannten Parametern Werte zu, entweder aus Positionsargumenten, aus
Schlüsselwortargumenten oder aus Standardwerten.  Ist die Form
"*identifier" vorhanden, wird sie mit einem Tupel initialisiert, das
alle überschüssigen Positionsargumente aufnimmt; der Standardwert ist
ein leeres Tupel. Ist die Form "**identifier" vorhanden, wird sie mit
einer neuen geordneten Zuordnung initialisiert, die alle
überschüssigen Schlüsselwortargumente aufnimmt; der Standardwert ist
eine neue leere Zuordnung desselben Typs.  Parameter nach "*" oder
"*identifier" sind reine Schlüsselwortparameter und dürfen nur über
Schlüsselwortargumente übergeben werden.  Parameter vor "/" sind reine
Positionsparameter und dürfen nur über Positionsargumente übergeben
werden.

Geändert in Version 3.8: Die Parametersyntax der Funktion "/" kann
verwendet werden, um rein positionelle Parameter anzugeben. Weitere
Informationen finden Sie unter **PEP 570**.

Parameters may have an *annotation* of the form "": expression""
following the parameter name.  Any parameter may have an annotation,
even those of the form "*identifier" or "**identifier". (As a special
case, parameters of the form "*identifier" may have an annotation "":
*expression"".) Functions may have "return" annotation of the form
""-> expression"" after the parameter list.  These annotations can be
any valid Python expression.  The presence of annotations does not
change the semantics of a function.  The annotation values are
available as values of a dictionary keyed by the parameters' names in
the "__annotations__" attribute of the function object.  If the
"annotations" import from "__future__" is used, annotations are
preserved as strings at runtime which enables postponed evaluation.
Otherwise, they are evaluated when the function definition is
executed.  In this case annotations may be evaluated in a different
order than they appear in the source code.

Geändert in Version 3.11: Parameter der Form "*identifier" können mit
der Anmerkung ": *expression" versehen sein. Siehe **PEP 646**.

Es ist auch möglich, anonyme Funktionen (Funktionen, die nicht an
einen Namen gebunden sind) zu erstellen, die direkt in Ausdrücken
verwendet werden können. Hierfür werden Lambda-Ausdrücke verwendet,
die im Abschnitt Lambdas beschrieben sind.  Beachten Sie, dass der
Lambda-Ausdruck lediglich eine Kurzschreibweise für eine vereinfachte
Funktionsdefinition ist; eine in einer "def" -Anweisung definierte
Funktion kann genau wie eine durch einen Lambda-Ausdruck definierte
Funktion weitergegeben oder einem anderen Namen zugewiesen werden. Die
Form "def" ist sogar noch leistungsfähiger, da sie die Ausführung
mehrerer Anweisungen und Annotationen ermöglicht.

**Anmerkung des Programmierers:** Funktionen sind Objekte erster
Klasse. Eine innerhalb einer Funktionsdefinition ausgeführte Anweisung
"def" definiert eine lokale Funktion, die zurückgegeben oder
weitergegeben werden kann. Freie Variablen, die in der verschachtelten
Funktion verwendet werden, können auf die lokalen Variablen der
Funktion zugreifen, die die "def"-Anweisung enthält. Weitere
Informationen finden Sie im Abschnitt Benennung und Zuordnung .

Siehe auch:

  **PEP 3107** - Funktionsanmerkungen
     Die ursprüngliche Spezifikation für Funktionsannotationen.

  **PEP 484** - Typ-Hinweise
     Definition einer einheitlichen Bedeutung für Anmerkungen:
     Typhinweise.

  **PEP 526** - Syntax für Variablenanmerkungen
     Möglichkeit, Typangaben für Variablendeklarationen zu machen,
     einschließlich Klassenvariablen und Instanzvariablen.

  **PEP 563** - Aufgeschobene Auswertung von Anmerkungen
     Unterstützung für Vorwärtsverweise innerhalb von Anmerkungen
     durch die Beibehaltung der Anmerkungen in Zeichenfolgenform zur
     Laufzeit anstelle einer sofortigen Auswertung.

  **PEP 318** - Dekoratoren für Funktionen und Methoden
     Es wurden Funktions- und Methoden-Dekoratoren eingeführt.
     Klassendekoratoren wurden in **PEP 3129** eingeführt.


8.8. Klassendefinitionen
========================

Eine Klassendefinition definiert ein Klassenobjekt (siehe Abschnitt
Die Standardtyp-Hierarchie):

   classdef    ::= [decorators] "class" classname [type_params] [inheritance] ":" suite
   inheritance ::= "(" [argument_list] ")"
   classname   ::= identifier

Eine Klassendefinition ist eine ausführbare Anweisung. Die
Vererbungsliste enthält in der Regel eine Auflistung von Basisklassen
(siehe Metaklassen für fortgeschrittenere Anwendungsmöglichkeiten),
daher sollte jedes Element der Liste zu einem Klassenobjekt
ausgewertet werden, das die Erstellung von Unterklassen zulässt.
Klassen ohne Vererbungsliste erben standardmäßig von der Basisklasse
"object" ; daher gilt:

   class Foo:
       pass

entspricht

   class Foo(object):
       pass

Die Suite der Klasse wird dann in einem neuen Ausführungsrahmen (siehe
Benennung und Zuordnung) unter Verwendung eines neu erstellten lokalen
Namensraums und des ursprünglichen globalen Namensraums ausgeführt.
(In der Regel enthält die Suite hauptsächlich Funktionsdefinitionen.)
Wenn die Suite der Klasse die Ausführung beendet hat, wird ihr
Ausführungsrahmen verworfen, ihr lokaler Namensraum jedoch
gespeichert. [5] Anschließend wird ein Klassenobjekt unter Verwendung
der Vererbungsliste für die Basisklassen und des gespeicherten lokalen
Namensraums für das Attributwörterbuch erstellt. Der Klassenname wird
im ursprünglichen lokalen Namensraum an dieses Klassenobjekt gebunden.

Die Reihenfolge, in der die Attribute im Klassenkörper definiert sind,
bleibt im "__dict__" der neuen Klasse erhalten. Beachten Sie, dass
dies nur unmittelbar nach der Erstellung der Klasse und nur für
Klassen gilt, die mithilfe der Definitionssyntax definiert wurden.

Die Erstellung von Klassen lässt sich mithilfe von Metaklassen
umfassend anpassen.

Auch Klassen können dekoriert werden: genau wie beim Dekorieren von
Funktionen,

   @f1(arg)
   @f2
   class Foo: pass

entspricht in etwa

   class Foo: pass
   Foo = f1(arg)(f2(Foo))

Die Auswertungsregeln für Dekoratorausdrücke entsprechen denen für
Funktionsdekoratoren. Das Ergebnis wird dann an den Klassennamen
gebunden.

Geändert in Version 3.9: Klassen können mit beliebigen gültigen
"assignment_expression" dekoriert werden. Früher war die Syntax
wesentlich restriktiver; Einzelheiten finden Sie unter **PEP 614**.

Eine Liste der Typ-Parameter kann unmittelbar nach dem Namen der
Klasse in eckigen Klammern angegeben werden. Dies signalisiert
statischen Typprüfern, dass es sich um eine generische Klasse handelt.
Zur Laufzeit können die Typ-Parameter über das Attribut
"__type_params__" der Klasse abgerufen werden. Weitere Informationen
finden Sie unter Generische Klassen.

Geändert in Version 3.12: Typ-Parameterlisten sind eine Neuerung in
Python 3.12.

**Anmerkung für Programmierer:** In der Klassendefinition definierte
Variablen sind Klassenattribute; sie werden von allen Instanzen
gemeinsam genutzt. Instanzattribute können in einer Methode mit
"self.name = value" gesetzt werden. Sowohl auf Klassen- als auch auf
Instanzattribute kann über die Notation "self.name" zugegriffen
werden, wobei ein Instanzattribut ein Klassenattribut mit demselben
Namen überdeckt, wenn auf diese Weise darauf zugegriffen wird.
Klassenattribute können als Standardwerte für Instanzattribute
verwendet werden, doch die Verwendung veränderbarer Werte kann zu
unerwarteten Ergebnissen führen.  Deskriptoren können verwendet
werden, um Instanzvariablen mit unterschiedlichen
Implementierungsdetails zu erstellen.

Siehe auch:

  **PEP 3115** - Metaklassen in Python 3000
     Der Vorschlag, durch den die Deklaration von Metaklassen auf die
     aktuelle Syntax umgestellt wurde, sowie die Semantik hinsichtlich
     der Konstruktion von Klassen mit Metaklassen.

  **PEP 3129** - Klassendekoratoren
     Der Vorschlag, mit dem Klassendekoratoren eingeführt wurden.
     Funktions- und Methodendekoratoren wurden unter **PEP 318**
     eingeführt.


8.9. Coroutinen
===============

Added in version 3.5.


8.9.1. Definition einer Coroutine-Funktion
------------------------------------------

   async_funcdef ::= [decorators] "async" "def" funcname "(" [parameter_list] ")"
                     ["->" expression] ":" suite

Die Ausführung von Python-Coroutinen kann an vielen Stellen
unterbrochen und wieder aufgenommen werden (siehe *coroutine*).
"await" -Ausdrücke, "async for" und "async with" können nur im Körper
einer Coroutine-Funktion verwendet werden.

Mit der Syntax "async def" definierte Funktionen sind immer
Coroutinen, auch wenn sie die Schlüsselwörter "await" oder "async"
nicht enthalten.

Es ist ein "SyntaxError", einen "yield from" -Ausdruck im Körper einer
Coroutine-Funktion zu verwenden.

Ein Beispiel für eine Coroutine-Funktion:

   async def func(param1, param2):
       do_stuff()
       await some_coroutine()

Geändert in Version 3.7: "await" und "async" sind nun Schlüsselwörter;
zuvor wurden sie nur innerhalb des Körpers einer Coroutine-Funktion
als solche behandelt.


8.9.2. Die Anweisung "async for"
--------------------------------

   async_for_stmt ::= "async" for_stmt

Ein *asynchrones Iterabel* stellt eine Methode "__aiter__" bereit, die
direkt einen *asynchronen Iterator* zurückgibt, der in seiner Methode
"__anext__" asynchronen Code aufrufen kann.

Die Anweisung "async for" ermöglicht eine bequeme Iteration über
asynchrone Iterables.

Der folgende Code:

   async for TARGET in ITER:
       SUITE
   else:
       SUITE2

Ist semantisch gleichbedeutend mit:

   iter = (ITER).__aiter__()
   running = True

   while running:
       try:
           TARGET = await iter.__anext__()
       except StopAsyncIteration:
           running = False
       else:
           SUITE
   else:
       SUITE2

mit der Ausnahme, dass für "__aiter__()" und "__anext__()" die
implizite Spezialmethoden-Suche verwendet wird.

Es ist ein "SyntaxError", eine "async for" -Anweisung außerhalb des
Körpers einer Coroutine-Funktion zu verwenden.


8.9.3. Die Anweisung "async with"
---------------------------------

   async_with_stmt ::= "async" with_stmt

Ein *asynchroner Kontextmanager* ist ein *Kontextmanager*, der die
Ausführung in seinen *enter*- und *exit*-Methoden unterbrechen kann.

Der folgende Code:

   async mit EXPRESSION als TARGET:
       SUITE

ist semantisch gleichbedeutend mit:

   manager = (EXPRESSION)
   aenter = manager.__aenter__
   aexit = manager.__aexit__
   value = await aenter()
   hit_except = False

   try:
       TARGET = value
       SUITE
   except:
       hit_except = True
       if not await aexit(*sys.exc_info()):
           raise
   finally:
       if not hit_except:
           await aexit(None, None, None)

mit der Ausnahme, dass für "__aenter__()" und "__aexit__()" die
implizite Spezialmethoden-Suche verwendet wird.

Es ist ein "SyntaxError", eine "async with" -Anweisung außerhalb des
Körpers einer Coroutine-Funktion zu verwenden.

Siehe auch:

  **PEP 492** - Coroutinen mit der "async"- und "await"-Syntax
     Der Vorschlag, durch den Coroutinen zu einem eigenständigen
     Konzept in Python wurden und die entsprechende Syntax hinzugefügt
     wurde.


8.10. Typenparameterlisten
==========================

Added in version 3.12.

Geändert in Version 3.13: Es wurde Unterstützung für Standardwerte
hinzugefügt (siehe **PEP 696**).

   type_params  ::= "[" type_param ("," type_param)* "]"
   type_param   ::= typevar | typevartuple | paramspec
   typevar      ::= identifier (":" expression)? ("=" expression)?
   typevartuple ::= "*" identifier ("=" expression)?
   paramspec    ::= "**" identifier ("=" expression)?

Funktionen (einschließlich Coroutinen), Klassen und Typalias können
eine Typ-Parameterliste enthalten:

   def max[T](args: list[T]) -> T:
       ...

   async def amax[T](args: list[T]) -> T:
       ...

   class Bag[T]:
       def __iter__(self) -> Iterator[T]:
           ...

       def add(self, arg: T) -> None:
           ...

   type ListOrSet[T] = list[T] | set[T]

Semantisch bedeutet dies, dass die Funktion, Klasse oder der Typalias
über eine Typvariable generisch ist. Diese Information wird in erster
Linie von statischen Typprüfern verwendet, und zur Laufzeit verhalten
sich generische Objekte weitgehend wie ihre nicht-generischen
Entsprechungen.

Typ-Parameter werden in eckigen Klammern ("[]") unmittelbar nach dem
Namen der Funktion, Klasse oder des Typ-Alias deklariert. Auf die Typ-
Parameter kann innerhalb des Geltungsbereichs des generischen Objekts
zugegriffen werden, anderswo jedoch nicht. Daher ist nach einer
Deklaration "def func[T](): pass" der Name "T" im Modul-
Geltungsbereich nicht verfügbar. Im Folgenden wird die Semantik
generischer Objekte genauer beschrieben. Der Geltungsbereich von Typ-
Parametern wird durch eine spezielle Funktion (technisch gesehen ein
Annotationsbereich) modelliert, die die Erstellung des generischen
Objekts umschließt.

Generische Funktionen, Klassen und Typaliasse verfügen über ein
Attribut "__type_params__", in dem ihre Typparameter aufgeführt sind.

Es gibt drei Arten von Typenparametern:

* "typing.TypeVar", eingeführt durch einen einfachen Namen (z. B.
  "T"). Semantisch gesehen stellt dies für einen Typprüfer einen
  einzelnen Typ dar.

* "typing.TypeVarTuple", eingeführt durch einen Namen, dem ein
  einzelnes Sternchen vorangestellt ist (z. B. "*Ts"). Semantisch
  steht dies für ein Tupel beliebiger Typen.

* "typing.ParamSpec", eingeleitet durch einen Namen, dem zwei
  Sternchen vorangestellt sind (z. B. "**P"). Semantisch gesehen steht
  dies für die Parameter eines aufrufbaren Objekts.

"typing.TypeVar" Deklarationen können *Grenzen* und *Einschränkungen*
mit einem Doppelpunkt (":") definieren, auf den ein Ausdruck folgt.
Ein einzelner Ausdruck nach dem Doppelpunkt bezeichnet eine Grenze (z.
B. "T: int"). Semantisch bedeutet dies, dass die "typing.TypeVar" nur
Typen darstellen kann, die ein Untertyp dieser Grenze sind. Ein in
Klammern gesetztes Tupel von Ausdrücken nach dem Doppelpunkt
bezeichnet eine Reihe von Einschränkungen (z. B. "T: (str, bytes)").
Jedes Element des Tupels sollte ein Typ sein (auch dies wird zur
Laufzeit nicht erzwungen). Eingeschränkte Typvariablen können nur
einen der Typen aus der Liste der Einschränkungen annehmen.

Bei "typing.TypeVar"s, die unter Verwendung der Typ-Parameterlisten-
Syntax deklariert wurden, werden die Grenzen und Einschränkungen nicht
bei der Erstellung des generischen Objekts ausgewertet, sondern erst
dann, wenn explizit über die Attribute "__bound__" und
"__constraints__" auf den Wert zugegriffen wird. Zu diesem Zweck
werden die Grenzen bzw. Einschränkungen in einem separaten
Annotationsbereich ausgewertet.

"typing.TypeVarTuple"s und "typing.ParamSpec"s dürfen keine
Begrenzungen oder Einschränkungen aufweisen.

Alle drei Varianten von Typparametern können zudem einen
*Standardwert* haben, der verwendet wird, wenn der Typparameter nicht
explizit angegeben wird. Dieser wird durch Anhängen eines einzelnen
Gleichheitszeichens ("="), gefolgt von einem Ausdruck, hinzugefügt.
Ähnlich wie die Grenzen und Einschränkungen von Typvariablen wird der
Standardwert nicht bei der Erstellung des Objekts ausgewertet, sondern
erst, wenn auf das Attribut "__default__" des Typparameters
zugegriffen wird. Zu diesem Zweck wird der Standardwert in einem
separaten Annotationsbereich ausgewertet. Wenn für einen Typparameter
kein Standardwert angegeben ist, wird das Attribut "__default__" auf
das spezielle Sentinel-Objekt "typing.NoDefault" gesetzt.

Das folgende Beispiel zeigt den vollständigen Satz zulässiger Typ-
Parameter-Deklarationen:

   def overly_generic[
      SimpleTypeVar,
      TypeVarWithDefault = int,
      TypeVarWithBound: int,
      TypeVarWithConstraints: (str, bytes),
      *SimpleTypeVarTuple = (int, float),
      **SimpleParamSpec = (str, bytearray),
   ](
      a: SimpleTypeVar,
      b: TypeVarWithDefault,
      c: TypeVarWithBound,
      d: Callable[SimpleParamSpec, TypeVarWithConstraints],
      *e: SimpleTypeVarTuple,
   ): ...


8.10.1. Generische Funktionen
-----------------------------

Generische Funktionen werden wie folgt deklariert:

   def func[T](arg: T): ...

Diese Syntax entspricht folgendem:

   annotation-def TYPE_PARAMS_OF_func():
       T = typing.TypeVar("T")
       def func(arg: T): ...
       func.__type_params__ = (T,)
       return func
   func = TYPE_PARAMS_OF_func()

Hier bezeichnet "annotation-def" einen Annotationsbereich, der zur
Laufzeit eigentlich an keinen Namen gebunden ist. (Bei der Übersetzung
wurde noch eine weitere Freiheit in Anspruch genommen: Die Syntax
greift nicht über Attributzugriff auf das Modul "typing" zu, sondern
erstellt direkt eine Instanz von "typing.TypeVar".)

Die Annotationen generischer Funktionen werden innerhalb des
Annotationsbereichs ausgewertet, der für die Deklaration der
Typparameter verwendet wird; die Standardwerte und Dekoratoren der
Funktion hingegen nicht.

Das folgende Beispiel veranschaulicht die Gültigkeitsbereichsregeln
für diese Fälle sowie für weitere Varianten von Typparametern:

   @decorator
   def func[T: int, *Ts, **P](*args: *Ts, arg: Callable[P, T] = some_default):
       ...

Abgesehen von der verzögerten Auswertung der Bindung "TypeVar"
entspricht dies folgendem Ausdruck:

   DEFAULT_OF_arg = some_default

   annotation-def TYPE_PARAMS_OF_func():

       annotation-def BOUND_OF_T():
           return int
       # Tatsächlich wird BOUND_OF_T() nur bei Bedarf ausgewertet.
       T = typing.TypeVar("T", bound=BOUND_OF_T())

       Ts = typing.TypeVarTuple("Ts")
       P = typing.ParamSpec("P")

       def func(*args: *Ts, arg: Callable[P, T] = DEFAULT_OF_arg):
           ...

       func.__type_params__ = (T, Ts, P)
       return func
   func = decorator(TYPE_PARAMS_OF_func())

Die großgeschriebenen Namen wie "DEFAULT_OF_arg" werden zur Laufzeit
eigentlich nicht gebunden.


8.10.2. Generische Klassen
--------------------------

Generische Klassen werden wie folgt deklariert:

   Klasse Bag[T]: ...

Diese Syntax entspricht folgendem:

   annotation-def TYPE_PARAMS_OF_Bag():
       T = typing.TypeVar("T")
       class Bag(typing.Generic[T]):
           __type_params__ = (T,)
           ...
       return Bag
   Bag = TYPE_PARAMS_OF_Bag()

Auch hier weist "annotation-def" (kein echtes Schlüsselwort) auf einen
Annotationsbereich hin, und der Name "TYPE_PARAMS_OF_Bag" wird zur
Laufzeit tatsächlich nicht gebunden.

Generische Klassen erben implizit von "typing.Generic". Die
Basisklassen und Schlüsselwortargumente generischer Klassen werden
innerhalb des Typbereichs für die Typparameter ausgewertet, während
Dekoratoren außerhalb dieses Bereichs ausgewertet werden. Dies wird
durch das folgende Beispiel veranschaulicht:

   @decorator
   class Bag(Base[T], arg=T): ...

Das entspricht folgendem:

   annotation-def TYPE_PARAMS_OF_Bag():
       T = typing.TypeVar("T")
       class Bag(Base[T], typing.Generic[T], arg=T):
           __type_params__ = (T,)
           ...
       return Bag
   Bag = decorator(TYPE_PARAMS_OF_Bag())


8.10.3. Generische Typaliase
----------------------------

Die Anweisung "type" kann auch zum Erstellen eines generischen
Typalias verwendet werden:

   Typ ListOrSet[T] = list[T] | set[T]

Abgesehen von der verzögerten Auswertung des Werts entspricht dies
folgendem Ausdruck:

   annotation-def TYPE_PARAMS_OF_ListOrSet():
       T = typing.TypeVar("T")

       annotation-def VALUE_OF_ListOrSet():
           return list[T] | set[T]
       # Tatsächlich wird der Wert verzögert ausgewertet
       return typing.TypeAliasType("ListOrSet", VALUE_OF_ListOrSet(), type_params=(T,))
   ListOrSet = TYPE_PARAMS_OF_ListOrSet()

Hier bezeichnet "annotation-def" (kein echtes Schlüsselwort) einen
Annotationsbereich. Die großgeschriebenen Namen wie
"TYPE_PARAMS_OF_ListOrSet" werden zur Laufzeit tatsächlich nicht
gebunden.

-[ Fußnoten ]-

[1] Die Ausnahme wird an den Aufrufstapel weitergegeben, es sei denn,
    es liegt eine "finally" -Klausel vor, die zufällig eine weitere
    Ausnahme auslöst. Diese neue Ausnahme führt dazu, dass die alte
    Ausnahme verloren geht.

[2] Beim Musterabgleich wird eine Sequenz als eine der folgenden
    Möglichkeiten definiert:

    * eine Klasse, die sich von "collections.abc.Sequence" ableitet

    * eine Python-Klasse, die als "collections.abc.Sequence"
      registriert ist

    * eine integrierte Klasse, bei der das (CPython-)
      "Py_TPFLAGS_SEQUENCE" -Bit gesetzt ist

    * eine Klasse, die von einer der oben genannten Klassen abgeleitet
      ist

    Die folgenden Klassen der Standardbibliothek sind Sequenzen:

    * "array.array"

    * "collections.deque"

    * "list"

    * "memoryview"

    * "range"

    * "tuple"

    Bemerkung:

      Subjektwerte vom Typ "str", "bytes" und "bytearray" entsprechen
      keinen Sequenzmustern.

[3] Beim Musterabgleich wird eine Zuordnung als eine der folgenden
    Möglichkeiten definiert:

    * eine Klasse, die sich von "collections.abc.Mapping" ableitet

    * eine Python-Klasse, die als "collections.abc.Mapping"
      regisirtiert wurde

    * eine integrierte Klasse, bei der das (CPython-)
      "Py_TPFLAGS_MAPPING" -Bit gesetzt ist

    * eine Klasse, die von einer der oben genannten Klassen abgeleitet
      ist

    Die Klassen "dict" und "types.MappingProxyType" aus der
    Standardbibliothek sind Zuordnungen.

[4] Ein String-Literal, das als erste Anweisung im Funktionskörper
    erscheint, wird in das Attribut "__doc__" der Funktion und damit
    in den *docstring* der Funktion umgewandelt.

[5] Ein String-Literal, das als erste Anweisung im Klassenkörper
    erscheint, wird in das Element "__doc__" des Namensraums und somit
    in das *docstring* der Klasse umgewandelt.
