4. Ausführungsmodell
********************


4.1. Aufbau eines Programms
===========================

Ein Python-Programm setzt sich aus Codeblöcken zusammen. Ein *Block*
ist ein Teil des Python-Programmtextes, der als Einheit ausgeführt
wird. Zu den Blöcken gehören: ein Modul, ein Funktionskörper und eine
Klassendefinition. Jeder interaktiv eingegebene Befehl ist ein Block.
Eine Skriptdatei (eine Datei, die dem Interpreter als Standardeingabe
übergeben oder als Befehlszeilenargument für den Interpreter angegeben
wird) ist ein Codeblock. Ein Skriptbefehl (ein Befehl, der in der
Befehlszeile des Interpreters mit der Option "-c" angegeben wird) ist
ein Codeblock. Ein Modul, das als Skript der obersten Ebene (als Modul
"__main__" ) über die Befehlszeile mit dem Argument "-m" ausgeführt
wird, ist ebenfalls ein Codeblock. Das an die integrierten Funktionen
"eval()" und "exec()" übergebene Zeichenfolgenargument ist ein
Codeblock.

Ein Codeblock wird in einem *Ausführungsrahmen* ausgeführt. Ein Rahmen
enthält einige Verwaltungsinformationen (die zur Fehlersuche dienen)
und legt fest, wo und wie die Ausführung fortgesetzt wird, nachdem die
Ausführung des Codeblocks abgeschlossen ist.


4.2. Benennung und Zuordnung
============================


4.2.1. Namensbindung
--------------------

*Namen* beziehen sich auf Objekte. Namen werden durch
Namensbindungsoperationen eingeführt.

Die folgenden Konstrukte binden Namen:

* Formale Parameter von Funktionen,

* Klassendefinitionen,

* Funktionsdefinitionen,

* Zuweisungsausdrücke,

* Ziele, die als Bezeichner gelten, wenn sie in einer Zuweisung
  vorkommen:

  * "for" Schleifenkopf,

  * nach "as" in einer "with" -Anweisung, einer "except" -Klausel,
    einer "except*" -Klausel oder im "as"-Muster beim strukturellen
    Musterabgleich,

  * in einem Erfassungsmuster beim strukturellen Musterabgleich

* "import" Aussagen.

* "type" Aussagen.

* Typ-Parameterlisten.

Die Anweisung "import" in der Form "from ... import *" bindet alle im
importierten Modul definierten Namen, mit Ausnahme derjenigen, die mit
einem Unterstrich beginnen. Diese Form darf nur auf Modulebene
verwendet werden.

Ein Ziel, das in einer Anweisung vom Typ "del" vorkommt, gilt für
diesen Zweck ebenfalls als gebunden (auch wenn die eigentliche
Semantik darin besteht, die Bindung des Namens aufzuheben).

Jede Zuweisungs- oder Importanweisung erfolgt innerhalb eines Blocks,
der durch eine Klassen- oder Funktionsdefinition definiert ist, oder
auf Modulebene (dem Code-Block der obersten Ebene).

If a name is bound in a block, it is a local variable of that block,
unless declared as "nonlocal" or "global".  If a name is bound at the
module level, it is a global variable.  (The variables of the module
code block are local and global.)  If a variable is used in a code
block but not defined there, it is a *free variable*.

Jedes Vorkommen eines Namens im Programmtext bezieht sich auf die
*Bindung* dieses Namens, die durch die folgenden
Namensauflösungsregeln festgelegt wird.


4.2.2. Namensauflösung
----------------------

Ein *Gültigkeitsbereich* legt fest, in welchem Umfang ein Name
innerhalb eines Blocks sichtbar ist. Wird eine lokale Variable in
einem Block definiert, erstreckt sich ihr Gültigkeitsbereich auf
diesen Block. Erfolgt die Definition in einem Funktionsblock,
erstreckt sich der Gültigkeitsbereich auf alle Blöcke, die in dem
definierenden Block enthalten sind, es sei denn, ein darin enthaltener
Block führt eine andere Bindung für den Namen ein.

Wenn ein Name in einem Codeblock verwendet wird, wird er anhand des
nächstgelegenen übergeordneten Gültigkeitsbereichs aufgelöst. Die
Menge aller solcher Gültigkeitsbereiche, die für einen Codeblock
sichtbar sind, wird als *Umgebung* des Blocks bezeichnet.

Wenn ein Name überhaupt nicht gefunden wird, wird eine Ausnahme vom
Typ "NameError" ausgelöst. Handelt es sich beim aktuellen
Gültigkeitsbereich um einen Funktionsbereich und bezieht sich der Name
auf eine lokale Variable, die an der Stelle, an der der Name verwendet
wird, noch nicht mit einem Wert belegt wurde, wird eine Ausnahme vom
Typ "UnboundLocalError" ausgelöst. "UnboundLocalError" ist eine
Unterklasse von "NameError" .

Wenn irgendwo innerhalb eines Codeblocks eine Namensbindung
stattfindet, werden alle Verwendungen des Namens innerhalb des Blocks
als Verweise auf den aktuellen Block behandelt. Dies kann zu Fehlern
führen, wenn ein Name innerhalb eines Blocks verwendet wird, bevor er
gebunden wurde. Diese Regel ist nicht ganz einfach zu verstehen.
Python kennt keine Deklarationen und erlaubt es, dass
Namensbindungsoperationen an beliebiger Stelle innerhalb eines
Codeblocks stattfinden.  Die lokalen Variablen eines Codeblocks lassen
sich ermitteln, indem der gesamte Text des Blocks auf
Namensbindungsoperationen durchsucht wird. Beispiele finden Sie im
FAQ-Eintrag zu UnboundLocalError.

Wenn die Anweisung "global" innerhalb eines Blocks auftritt, beziehen
sich alle Verwendungen der in der Anweisung angegebenen Namen auf die
Zuordnungen dieser Namen im obersten Namensraum.  Namen werden im
obersten Namensraum aufgelöst, indem der globale Namensraum, d. h. der
Namensraum des Moduls, das den Codeblock enthält, sowie der
"builtins"-Namensraum, der Namensraum des Moduls "builtins",
durchsucht werden. Der globale Namensraum wird zuerst durchsucht.
Werden die Namen dort nicht gefunden, wird als Nächstes der
"builtins"-Namensraum durchsucht. Werden die Namen auch im
"builtins"-Namensraum nicht gefunden, werden neue Variablen im
globalen Namensraum angelegt. Die Anweisung "global" muss allen
Verwendungen der aufgeführten Namen vorangestellt werden.

Die Anweisung "global" hat denselben Geltungsbereich wie eine
Namensbindung im selben Block. Wenn der nächstübergeordnete
Geltungsbereich einer freien Variablen eine globale Anweisung enthält,
wird die freie Variable als globale Variable behandelt.

Die Anweisung "nonlocal" bewirkt, dass die entsprechenden Namen auf
zuvor gebundene Variablen im nächstübergeordneten
Funktionsgültigkeitsbereich verweisen. Wenn der angegebene Name in
keinem übergeordneten Funktionsgültigkeitsbereich existiert, wird zur
Kompilierungszeit ein "SyntaxError" ausgelöst. Typ-Parameter können
mit der Anweisung "nonlocal" nicht neu gebunden werden.

Der Namensraum für ein Modul wird automatisch angelegt, sobald das
Modul zum ersten Mal importiert wird. Das Hauptmodul eines Skripts
heißt immer "__main__" .

Klassendefinitionsblöcke und Argumente für "exec()" und "eval()"
stellen im Zusammenhang mit der Namensauflösung einen Sonderfall dar.
Eine Klassendefinition ist eine ausführbare Anweisung, die Namen
verwenden und definieren kann. Diese Verweise folgen den üblichen
Regeln für die Namensauflösung, mit der Ausnahme, dass ungebundene
lokale Variablen im globalen Namensraum gesucht werden. Der Namensraum
der Klassendefinition wird zum Attributwörterbuch der Klasse. Der
Geltungsbereich von Namen, die in einem Klassenblock definiert werden,
ist auf den Klassenblock beschränkt; er erstreckt sich nicht auf die
Codeblöcke von Methoden. Dies umfasst Comprehensions und
Generatorausdrücke, jedoch nicht Annotations-Geltungsbereiche, die
Zugriff auf die Geltungsbereiche ihrer umschließenden Klassen haben.
Das bedeutet, dass Folgendes fehlschlagen wird:

   Klasse A:
       a = 42
       b = list(a + i for i in range(10))

Folgendes wird jedoch funktionieren:

   Klasse A:
       Typ Alias = Nested
       Klasse Nested: pass

   print(A.Alias.__value__)  # <type 'A.Nested'>


4.2.3. Gültigkeitsbereiche von Annotationen
-------------------------------------------

Type parameter lists and "type" statements introduce *annotation
scopes*, which behave mostly like function scopes, but with some
exceptions discussed below. *Annotations* currently do not use
annotation scopes, but they are expected to use annotation scopes in
Python 3.13 when **PEP 649** is implemented.

Annotationsbereiche werden in den folgenden Kontexten verwendet:

* Typ-Parameterlisten für generische Typ-Aliase.

* Typ-Parameterlisten für generische Funktionen. Die Annotationen
  einer generischen Funktion werden innerhalb des Annotationsbereichs
  ausgeführt, ihre Standardwerte und Dekoratoren hingegen nicht.

* Typ-Parameterlisten für generische Klassen. Die Basisklassen und
  Schlüsselwortargumente einer generischen Klasse werden innerhalb des
  Annotationsbereichs ausgeführt, ihre Dekoratoren jedoch nicht.

* The bounds and constraints for type variables (lazily evaluated).

* Der Wert von Typaliasen (:ref:` <lazy-evaluation>`, die verzögert
  ausgewertet werden).

Annotations-Gültigkeitsbereiche unterscheiden sich in folgenden
Punkten von Funktions-Gültigkeitsbereichen:

* Annotationsbereiche haben Zugriff auf den Namensraum ihrer
  übergeordneten Klasse. Befindet sich ein Annotationsbereich
  unmittelbar innerhalb eines Klassenbereichs oder innerhalb eines
  anderen Annotationsbereichs, der sich wiederum unmittelbar innerhalb
  eines Klassenbereichs befindet, kann der Code im Annotationsbereich
  auf im Klassenbereich definierte Namen zugreifen, als würde er
  direkt innerhalb des Klassenkörpers ausgeführt. Dies steht im
  Gegensatz zu regulären, innerhalb von Klassen definierten
  Funktionen, die keinen Zugriff auf im Klassenbereich definierte
  Namen haben.

* Ausdrücke in Annotationsbereichen dürfen keine Ausdrücke vom Typ
  "yield", "yield from", "await" oder ":=" enthalten. (Diese Ausdrücke
  sind in anderen Bereichen zulässig, die innerhalb des
  Annotationsbereichs enthalten sind.)

* Namen, die in Annotationsbereichen definiert wurden, können nicht
  mit "nonlocal"-Anweisungen in inneren Bereichen neu definiert
  werden. Dies betrifft ausschließlich Typparameter, da keine anderen
  syntaktischen Elemente, die innerhalb von Annotationsbereichen
  vorkommen können, neue Namen einführen können.

* Annotationsbereiche verfügen zwar über einen internen Namen, dieser
  Name spiegelt sich jedoch nicht im *qualifizierten Namen* der
  innerhalb des Bereichs definierten Objekte wider. Stattdessen
  entspricht der "__qualname__" solcher Objekte dem, als wäre das
  Objekt im übergeordneten Bereich definiert.

Added in version 3.12: Annotationsbereiche wurden in Python 3.12 als
Teil von **PEP 695** eingeführt.


4.2.4. Verzögerte Auswertung
----------------------------

The values of type aliases created through the "type" statement are
*lazily evaluated*. The same applies to the bounds and constraints of
type variables created through the type parameter syntax. This means
that they are not evaluated when the type alias or type variable is
created. Instead, they are only evaluated when doing so is necessary
to resolve an attribute access.

Beispiel:

   >>> type Alias = 1/0
   >>> Alias.__value__
   Traceback (most recent call last):
     ...
   ZeroDivisionError: division by zero
   >>> def func[T: 1/0](): pass
   >>> T = func.__type_params__[0]
   >>> T.__bound__
   Traceback (most recent call last):
     ...
   ZeroDivisionError: division by zero

Hier wird die Ausnahme nur ausgelöst, wenn auf das Attribut
"__value__"  des Typalias oder auf das Attribut "__bound__" der
Typvariablen zugegriffen wird.

Dieses Verhalten ist vor allem bei Verweisen auf Typen nützlich, die
zum Zeitpunkt der Erstellung des Typalias oder der Typvariablen noch
nicht definiert waren. So ermöglicht die verzögerte Auswertung
beispielsweise die Erstellung von gegenseitig rekursiven Typalias:

   from typing import Literal

   type SimpleExpr = int | Parenthesized
   type Parenthesized = tuple[Literal["("], Expr, Literal[")"]]
   type Expr = SimpleExpr | tuple[SimpleExpr, Literal["+", "-"], Expr]

Verzögerte ausgewertete Werte werden im Annotationsbereich
ausgewertet, was bedeutet, dass Namen, die innerhalb des
verzögertausgewerteten Werts vorkommen, so nachgeschlagen werden, als
würden sie im unmittelbar umgebenden Bereich verwendet.

Added in version 3.12.


4.2.5. Eingebaute Funktionen und eingeschränkte Ausführung
----------------------------------------------------------

Benutzer sollten "__builtins__" nicht ändern; es handelt sich dabei
ausschließlich um ein Implementierungsdetail. Benutzer, die Werte im
Namespace "builtins" überschreiben möchten, sollten das Modul
"builtins" über "import" laden und dessen Attribute entsprechend
anpassen.

Der mit der Ausführung eines Codeblocks verbundene
"builtins"-Namensraum wird tatsächlich durch Abfrage des Namens
"__builtins__" in dessen globalem Namensraum ermittelt; dabei sollte
es sich um ein Wörterbuch oder ein Modul handeln (im letzteren Fall
wird das Wörterbuch des Moduls verwendet).  Standardmäßig ist
"__builtins__" im Modul "__main__" das eingebaute Modul "builtins" ;
in jedem anderen Modul ist "__builtins__" ein Alias für das Wörterbuch
des Moduls "builtins" selbst.


4.2.6. Interaktion mit dynamischen Funktionen
---------------------------------------------

Die Auflösung freier Variablen erfolgt zur Laufzeit und nicht zur
Kompilierungszeit. Das bedeutet, dass der folgende Code 42 ausgibt:

   i = 10
   def f():
       print(i)
   i = 42
   f()

Die Funktionen "eval()" und "exec()" haben keinen Zugriff auf die
vollständige Umgebung zur Namensauflösung.  Namen können im lokalen
und globalen Namensraum des Aufrufers aufgelöst werden. Freie
Variablen werden nicht im nächstübergeordneten Namensraum, sondern im
globalen Namensraum aufgelöst. [1] Die Funktionen "exec()" und
"eval()" verfügen über optionale Argumente, um den globalen und
lokalen Namensraum zu überschreiben. Wird nur ein Namensraum
angegeben, wird dieser für beide verwendet.


4.3. Ausnahmen
==============

Ausnahmen dienen dazu, den normalen Kontrollfluss eines Codeblocks zu
unterbrechen, um Fehler oder andere Ausnahmebedingungen zu behandeln.
Eine Ausnahme wird an der Stelle *ausgelöst*, an der der Fehler
erkannt wird; sie kann vom umgebenden Codeblock oder von jedem
Codeblock *behandelt* werden, der den Codeblock, in dem der Fehler
aufgetreten ist, direkt oder indirekt aufgerufen hat.

Der Python-Interpreter löst eine Ausnahme aus, wenn er einen
Laufzeitfehler (wie beispielsweise eine Division durch Null)
feststellt. Ein Python-Programm kann zudem mit der Anweisung "raise"
explizit eine Ausnahme auslösen. Ausnahmebehandler werden mit der
Anweisung "try"... "except" festgelegt.  Die Klausel "finally" einer
solchen Anweisung kann verwendet werden, um Aufräumcode anzugeben, der
die Ausnahme nicht behandelt, sondern unabhängig davon ausgeführt
wird, ob im vorangehenden Code eine Ausnahme aufgetreten ist oder
nicht.

Python verwendet das "Termination"-Modell der Fehlerbehandlung: Ein
Ausnahmebehandler kann zwar feststellen, was passiert ist, und die
Ausführung auf einer übergeordneten Ebene fortsetzen, aber er kann die
Fehlerursache nicht beheben und den fehlgeschlagenen Vorgang nicht
wiederholen (außer durch erneutes Ausführen des fehlerhaften
Codeabschnitts von Anfang an).

Wird eine Ausnahme überhaupt nicht abgefangen, bricht der Interpreter
die Ausführung des Programms ab oder kehrt zu seiner interaktiven
Hauptschleife zurück. In beiden Fällen gibt er einen Stack-Traceback
aus, es sei denn, es handelt sich um die Ausnahme "SystemExit" .

Ausnahmen werden anhand von Klasseninstanzen identifiziert. Die
Klausel "except" wird je nach Klasse der Instanz ausgewählt: Sie muss
auf die Klasse der Instanz oder auf eine *nicht-virtuelle Basisklasse*
derselben verweisen. Die Instanz kann vom Handler empfangen werden und
zusätzliche Informationen über die Ausnahmebedingung enthalten.

Bemerkung:

  Ausnahmemeldungen sind nicht Teil der Python-API. Ihr Inhalt kann
  sich von einer Python-Version zur nächsten ohne Vorwarnung ändern,
  weshalb sich Code, der unter mehreren Versionen des Interpreters
  ausgeführt wird, nicht darauf verlassen sollte.

Siehe auch die Beschreibung der Anweisung "try" im Abschnitt Die  try
Anweisung und der Anweisung "raise" im Abschnitt Die raise Anweisung.

-[ Fußnoten ]-

[1] Diese Einschränkung ergibt sich daraus, dass der Code, der durch
    diese Operationen ausgeführt wird, zum Zeitpunkt der Kompilierung
    des Moduls noch nicht verfügbar ist.
