3. Datenmodell
**************


3.1. Objekte, Werte und Typen
=============================

*Objekte* sind Pythons Abstraktion für Daten. Alle Daten in einem
Python-Programm werden durch Objekte oder durch Beziehungen zwischen
Objekten dargestellt. Selbst Code wird durch Objekte dargestellt.

Jedes Objekt hat eine Identität, einen Typ und einen Wert. Die
*Identität* eines Objekts ändert sich nach seiner Erstellung nie; man
kann sie sich als die Adresse des Objekts im Speicher vorstellen. Der
Operator ` "is" ` vergleicht die Identität zweier Objekte; die
Funktion ` "id()" ` gibt eine Ganzzahl zurück, die deren Identität
darstellt.

Bei CPython ist ` "id(x)" ` die Speicheradresse, an der ` "x" `
gespeichert ist.

Der Typ eines Objekts bestimmt, welche Operationen das Objekt
unterstützt (z. B. „Hat es eine Länge?“), und definiert zudem die
möglichen Werte für Objekte dieses Typs. Die Funktion „ "type()" “
gibt den Typ eines Objekts zurück (der selbst ein Objekt ist).  Genau
wie seine Identität ist auch der *type* eines Objekts unveränderlich.
[1]

Der *Wert* einiger Objekte kann sich ändern. Objekte, deren Wert sich
ändern kann, werden als *veränderbar* bezeichnet; Objekte, deren Wert
nach ihrer Erstellung unveränderlich ist, werden als *unveränderlich*
bezeichnet. (Der Wert eines unveränderlichen Container-Objekts, das
eine Referenz auf ein veränderliches Objekt enthält, kann sich ändern,
wenn der Wert des letzteren geändert wird; der Container gilt jedoch
weiterhin als unveränderlich, da die von ihm enthaltene Sammlung von
Objekten nicht verändert werden kann.  Unveränderlichkeit ist also
nicht streng genommen dasselbe wie ein unveränderlicher Wert, sondern
ein subtilerer Begriff.) Die Veränderbarkeit eines Objekts wird durch
seinen Typ bestimmt; so sind beispielsweise Zahlen, Zeichenketten und
Tupel unveränderlich, während Wörterbücher und Listen veränderbar
sind.

Objekte werden niemals explizit zerstört; wenn sie jedoch unerreichbar
werden, können sie durch die Garbage Collection entfernt werden. Eine
Implementierung darf die Garbage Collection aufschieben oder ganz
weglassen – es ist eine Frage der Implementierungsqualität, wie die
Garbage Collection umgesetzt wird, solange keine Objekte entfernt
werden, die noch erreichbar sind.

CPython verwendet derzeit ein Referenzzählverfahren mit (optionaler)
verzögerter Erkennung zyklisch verknüpfter Speicherabfälle, das die
meisten Objekte sammelt, sobald sie unerreichbar werden; es ist jedoch
nicht garantiert, dass Speicherabfälle mit zirkulären Referenzen
gesammelt werden. Informationen zur Steuerung der Sammlung zyklischer
Speicherabfälle findest du in der Dokumentation des Moduls „ "gc" “.
Andere Implementierungen verhalten sich anders, und CPython kann sich
ändern. Verlasse dich sich nicht darauf, dass Objekte sofort
freigegeben werden, sobald sie unerreichbar werden (daher solltest du
Dateien immer explizit schließen).

Beachte, dass die Verwendung der Tracing- oder Debugging-Funktionen
der Implementierung dazu führen kann, dass Objekte erhalten bleiben,
die normalerweise vom Garbage Collector entfernt würden. Beachte
außerdem, dass das Abfangen einer Ausnahme mit einer Anweisung wie „
"try"..."except" “ dazu führen kann, dass Objekte erhalten bleiben.

Einige Objekte enthalten Verweise auf „externe“ Ressourcen wie
geöffnete Dateien oder Fenster. Es wird davon ausgegangen, dass diese
Ressourcen freigegeben werden, wenn das Objekt von der Garbage
Collection entfernt wird; da jedoch nicht garantiert ist, dass eine
Garbage Collection stattfindet, bieten solche Objekte auch eine
explizite Möglichkeit, die externe Ressource freizugeben, in der Regel
über die Methode ` "close()" *. Es wird dringend empfohlen, solche
Objekte explizit zu schließen. Die Anweisung `
:keyword:`try*..."finally" ` und die Anweisung ` "with" ` bieten
bequeme Möglichkeiten, dies zu tun.

Manche Objekte enthalten Verweise auf andere Objekte; diese werden als
*Container* bezeichnet. Beispiele für Container sind Tupel, Listen und
Wörterbücher. Die Verweise sind Teil des Werts eines Containers.  Wenn
wir vom Wert eines Containers sprechen, meinen wir in den meisten
Fällen die Werte und nicht die Identitäten der enthaltenen Objekte;
wenn wir jedoch von der Veränderbarkeit eines Containers sprechen,
sind nur die Identitäten der unmittelbar enthaltenen Objekte gemeint.
Wenn also ein unveränderlicher Container (wie ein Tupel) einen Verweis
auf ein veränderliches Objekt enthält, ändert sich sein Wert, sobald
dieses veränderliche Objekt geändert wird.

Typen beeinflussen nahezu alle Aspekte des Objektverhaltens. Selbst
die Bedeutung der Objektidentität wird in gewisser Weise beeinflusst:
Bei unveränderlichen Typen können Operationen, die neue Werte
berechnen, tatsächlich eine Referenz auf ein beliebiges vorhandenes
Objekt desselben Typs und Werts zurückgeben, während dies bei
veränderlichen Objekten nicht zulässig ist. Beispielsweise können nach
der Ausführung von ` "a = 1; b = 1`" die Variablen *a* und *b* je nach
Implementierung auf dasselbe Objekt mit dem Wert „eins“ verweisen oder
auch nicht. Dies liegt daran, dass ` "int" ` ein unveränderlicher Typ
ist, sodass die Referenz auf ` "1" ` wiederverwendet werden kann.
Dieses Verhalten hängt von der verwendeten Implementierung ab und
sollte daher nicht als verlässlich angesehen werden; es ist jedoch
etwas, das man bei der Verwendung von Objektidentitätsprüfungen
beachten sollte. Nach "c = []; d = []" ist jedoch garantiert, dass *c*
und *d* auf zwei verschiedene, eindeutige, neu erstellte leere Listen
verweisen. (Beachte, dass "e = f = []" sowohl *e* als auch *f* das
*gleiche* Objekt zuweist.)


3.2. Die Standardtyp-Hierarchie
===============================

Im Folgenden findest du eine Liste der in Python integrierten Typen.
Erweiterungsmodule (die je nach Implementierung in C, Java oder
anderen Sprachen geschrieben sind) können zusätzliche Typen
definieren.  Zukünftige Versionen von Python könnten der
Typenhierarchie weitere Typen hinzufügen (z. B. rationale Zahlen,
effizient gespeicherte Arrays von Ganzzahlen usw.), obwohl solche
Ergänzungen häufig stattdessen über die Standardbibliothek
bereitgestellt werden.

Einige der nachstehenden Typbeschreibungen enthalten einen Absatz, in
dem „besondere Attribute“ aufgeführt sind. Dabei handelt es sich um
Attribute, die Zugriff auf die Implementierung gewähren und nicht für
den allgemeinen Gebrauch bestimmt sind. Ihre Definition kann sich in
Zukunft ändern.


3.2.1. Keine
------------

Dieser Typ hat einen einzigen Wert. Es gibt ein einziges Objekt mit
diesem Wert. Der Zugriff auf dieses Objekt erfolgt über den
integrierten Namen „ "None" “. Er wird in vielen Situationen
verwendet, um das Fehlen eines Werts anzuzeigen, z. B. wird er von
Funktionen zurückgegeben, die explizit nichts zurückgeben. Sein
Wahrheitswert ist „false“.


3.2.2. Nicht implementiert
--------------------------

Dieser Typ hat einen einzigen Wert. Es gibt ein einziges Objekt mit
diesem Wert. Der Zugriff auf dieses Objekt erfolgt über den
integrierten Namen „ "NotImplemented" “. Numerische Methoden und
erweiterte Vergleichsmethoden sollten diesen Wert zurückgeben, wenn
sie die Operation für die angegebenen Operanden nicht implementieren.
(Der Interpreter versucht dann, je nach Operator, die reflektierte
Operation oder eine andere Ausweichlösung.)  Er sollte nicht in einem
booleschen Kontext ausgewertet werden.

Weitere Informationen findest du unter Implementing the arithmetic
operations.

Geändert in Version 3.9: Evaluating "NotImplemented" in a boolean
context is deprecated. While it currently evaluates as true, it will
emit a "DeprecationWarning". It will raise a "TypeError" in a future
version of Python.


3.2.3. Auslassungspunkte
------------------------

Dieser Typ hat einen einzigen Wert. Es gibt ein einziges Objekt mit
diesem Wert. Der Zugriff auf dieses Objekt erfolgt über das Literal „
"..." “ oder den integrierten Namen „ "Ellipsis" “. Sein Wahrheitswert
ist „true“.


3.2.4. "numbers.Number"
-----------------------

Diese werden durch numerische Literale erstellt und als Ergebnisse von
arithmetischen Operatoren und integrierten arithmetischen Funktionen
zurückgegeben. Numerische Objekte sind unveränderlich; sobald sie
erstellt wurden, ändert sich ihr Wert nie mehr. Python-Zahlen stehen
natürlich in engem Zusammenhang mit mathematischen Zahlen, unterliegen
jedoch den Einschränkungen der numerischen Darstellung in Computern.

Die Zeichenfolgendarstellungen der numerischen Klassen, die mit
"__repr__()" und "__str__()" berechnet werden, weisen folgende
Eigenschaften auf:

* Es handelt sich um gültige numerische Literale, die, wenn sie an den
  Konstruktor ihrer Klasse übergeben werden, ein Objekt erzeugen,
  dessen Wert dem des ursprünglichen numerischen Werts entspricht.

* Die Darstellung erfolgt, soweit möglich, im Dezimalsystem.

* Führende Nullen werden nicht angezeigt, möglicherweise mit Ausnahme
  einer einzelnen Null vor dem Dezimalpunkt.

* Nachgestellte Nullen werden nicht angezeigt, möglicherweise mit
  Ausnahme einer einzelnen Null nach dem Komma.

* Ein Vorzeichen wird nur angezeigt, wenn die Zahl negativ ist.

Python unterscheidet zwischen Ganzzahlen, Gleitkommazahlen und
komplexen Zahlen:


3.2.4.1. "numbers.Integral"
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Diese stellen Elemente der mathematischen Menge der ganzen Zahlen
(positive und negative) dar.

Bemerkung:

  Die Regeln für die Darstellung von Ganzzahlen sollen eine möglichst
  aussagekräftige Interpretation von Verschiebungs- und
  Maskierungsoperationen mit negativen Ganzzahlen ermöglichen.

Es gibt zwei Arten von ganzen Zahlen:

Ganzzahlen ("int")
   Diese stellen Zahlen in einem unbegrenzten Bereich dar, der
   lediglich durch den verfügbaren (virtuellen) Speicher begrenzt ist.
   Für Verschiebungs- und Maskierungsoperationen wird eine binäre
   Darstellung vorausgesetzt, und negative Zahlen werden in einer
   Variante des 2er-Komplements dargestellt, die den Anschein einer
   unendlichen Kette von Vorzeichenbits erweckt, die sich nach links
   erstreckt.

Boolesche Werte ("bool")
   Diese stehen für die Wahrheitswerte „False“ und „True“. Die beiden
   Objekte, die die Werte „ "False" “ und „ "True" “ darstellen, sind
   die einzigen booleschen Objekte. Der Typ „Boolean“ ist ein Untertyp
   des Typs „Integer“, und boolesche Werte verhalten sich in fast
   allen Kontexten wie die Werte 0 bzw. 1. Eine Ausnahme bildet die
   Konvertierung in eine Zeichenkette, bei der jeweils die
   Zeichenketten „ ""False"" “ bzw. „ ""True"" “ zurückgegeben werden.


3.2.4.2. "numbers.Real" ("float")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Hierbei handelt es sich um Gleitkommazahlen mit doppelter Genauigkeit
auf Maschinenebene. Was den zulässigen Wertebereich und den Umgang mit
Überläufen betrifft, sind sie von der zugrunde liegenden
Maschinenarchitektur (und der C- oder Java-Implementierung) abhängig.
Python unterstützt keine Gleitkommazahlen mit einfacher Genauigkeit;
die Einsparungen bei Prozessor- und Speicherverbrauch, die
normalerweise der Grund für deren Verwendung sind, werden durch den
Overhead bei der Verwendung von Objekten in Python bei weitem
übertroffen, sodass es keinen Grund gibt, die Sprache mit zwei Arten
von Gleitkommazahlen zu verkomplizieren.


3.2.4.3. "numbers.Complex" ("complex")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Diese stellen komplexe Zahlen als Paar von Gleitkommazahlen mit
doppelter Genauigkeit auf Maschinenebene dar. Es gelten dieselben
Einschränkungen wie bei Gleitkommazahlen. Der Realteil und der
Imaginärteil einer komplexen Zahl "z" können über die
schreibgeschützten Attribute "z.real" und "z.imag" abgerufen werden.


3.2.5. Sequenzen
----------------

Diese stellen endliche, geordnete Mengen dar, die durch nicht-negative
Zahlen indiziert sind. Die integrierte Funktion "len()" gibt die
Anzahl der Elemente einer Folge zurück. Wenn die Länge einer Folge *n*
beträgt, enthält die Indexmenge die Zahlen 0, 1, ..., *n*-1.  Das
Element *i* der Folge *a* wird mit "a[i]" ausgewählt. Einige Folgen,
darunter auch integrierte Folgen, interpretieren negative Indizes so,
dass die Länge der Folge addiert wird. Beispielsweise entspricht
"a[-2]" dem Wert "a[n-2]", dem vorletzten Element der Folge a mit der
Länge "n".

Sequences also support slicing: "a[i:j]" selects all items with index
*k* such that *i* "<=" *k* "<" *j*.  When used as an expression, a
slice is a sequence of the same type. The comment above about negative
indexes also applies to negative slice positions.

Einige Sequenzen unterstützen zudem „erweitertes Slicing“ mit einem
dritten „step“-Parameter: "a[i:j:k]" wählt alle Elemente von *a* mit
dem Index *x* aus, wobei "x = i + n*k", *n* ">=", "0" und *i* "<=" *x*
"<" *j* gilt.

Sequenzen werden nach ihrer Mutabilität unterschieden:


3.2.5.1. Unveränderliche Sequenzen
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Ein Objekt eines unveränderlichen Sequenztyps kann nach seiner
Erstellung nicht mehr geändert werden. (Wenn das Objekt Verweise auf
andere Objekte enthält, können diese anderen Objekte veränderbar sein
und geändert werden; die Sammlung der Objekte, auf die ein
unveränderliches Objekt direkt verweist, darf sich jedoch nicht
ändern.)

Die folgenden Typen sind unveränderliche Sequenzen:

Zeichenfolgen
   A string is a sequence of values that represent Unicode code
   points. All the code points in the range "U+0000 - U+10FFFF" can be
   represented in a string.  Python doesn't have a char type; instead,
   every code point in the string is represented as a string object
   with length "1".  The built-in function "ord()" converts a code
   point from its string form to an integer in the range "0 - 10FFFF";
   "chr()" converts an integer in the range "0 - 10FFFF" to the
   corresponding length "1" string object. "str.encode()" can be used
   to convert a "str" to "bytes" using the given text encoding, and
   "bytes.decode()" can be used to achieve the opposite.

Tupel
   The items of a tuple are arbitrary Python objects. Tuples of two or
   more items are formed by comma-separated lists of expressions.  A
   tuple of one item (a 'singleton') can be formed by affixing a comma
   to an expression (an expression by itself does not create a tuple,
   since parentheses must be usable for grouping of expressions).  An
   empty tuple can be formed by an empty pair of parentheses.

Bytes
   A bytes object is an immutable array.  The items are 8-bit bytes,
   represented by integers in the range 0 <= x < 256.  Bytes literals
   (like "b'abc'") and the built-in "bytes()" constructor can be used
   to create bytes objects.  Also, bytes objects can be decoded to
   strings via the "decode()" method.


3.2.5.2. Veränderbare Sequenzen
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Veränderbare Sequenzen können nach ihrer Erstellung geändert werden.
Die Notationen für Abonnements und Slicing können als Ziel von
Zuweisungs- und Löschanweisungen ( "del" ) verwendet werden.

Bemerkung:

  Die Module „ "collections" “ und „ "array" “ enthalten weitere
  Beispiele für veränderbare Sequenztypen.

Derzeit gibt es zwei intrinsisch veränderbare Sequenztypen:

Listen
   Die Elemente einer Liste sind beliebige Python-Objekte. Listen
   werden gebildet, indem man eine durch Kommas getrennte Folge von
   Ausdrücken in eckige Klammern setzt. (Beachte, dass es keine
   Sonderfälle gibt, um Listen der Länge 0 oder 1 zu bilden.)

Byte-Arrays
   Ein Bytearray-Objekt ist ein veränderbares Array. Es wird mit dem
   integrierten Konstruktor „ "bytearray()" “ erstellt. Abgesehen
   davon, dass es veränderbar (und daher nicht hashbar) ist, bietet
   ein Bytearray ansonsten dieselbe Schnittstelle und Funktionalität
   wie unveränderliche „ "bytes" “-Objekte.


3.2.6. Mengenarten
------------------

Diese stellen ungeordnete, endliche Mengen einzigartiger,
unveränderlicher Objekte dar. Als solche können sie nicht durch einen
Index indiziert werden. Sie können jedoch durchlaufen werden, und die
integrierte Funktion ` "len()" ` gibt die Anzahl der Elemente in einer
Menge zurück. Häufige Anwendungsfälle für Mengen sind schnelle
Zugehörigkeitsprüfungen, das Entfernen von Duplikaten aus einer Folge
sowie die Berechnung mathematischer Operationen wie Schnitt,
Vereinigung, Differenz und symmetrische Differenz.

Für Elemente einer Menge gelten dieselben Unveränderlichkeitsregeln
wie für Schlüssel in einem Wörterbuch. Beachte, dass numerische Typen
den üblichen Regeln für den numerischen Vergleich folgen: Wenn zwei
Zahlen gleich sind (z. B. "1" und "1.0"), kann nur eine davon in einer
Menge enthalten sein.

Derzeit gibt es zwei intrinsische Mengenarten:

Sets
   Diese stellen eine veränderbare Menge dar. Sie werden durch den
   integrierten Konstruktor „ "set()" “ erstellt und können
   anschließend durch verschiedene Methoden, wie beispielsweise „
   "add()" “, geändert werden.

Gefrorene Sets
   Diese stellen eine unveränderliche Menge dar. Sie werden durch den
   integrierten Konstruktor "frozenset()" erstellt. Da ein „frozenset“
   unveränderlich und *hashable* ist, kann es erneut als Element einer
   anderen Menge oder als Schlüssel in einem Wörterbuch verwendet
   werden.


3.2.7. Zuordnungen
------------------

Diese stellen endliche Mengen von Objekten dar, die durch beliebige
Indexmengen indiziert sind. Die Indexnotation "a[k]" wählt das Element
aus, das durch "k" indiziert ist, aus der Zuordnung "a"; dies kann in
Ausdrücken sowie als Ziel von Zuweisungen oder "del" -Anweisungen
verwendet werden. Die integrierte Funktion "len()" gibt die Anzahl der
Elemente in einer Zuordnung zurück.

Derzeit gibt es einen einzigen intrinsischen Abbildungstyp:


3.2.7.1. Wörterbücher
~~~~~~~~~~~~~~~~~~~~~

Diese stellen endliche Mengen von Objekten dar, die durch nahezu
beliebige Werte indiziert sind. Die einzigen Wertetypen, die nicht als
Schlüssel zulässig sind, sind Werte, die Listen, Wörterbücher oder
andere veränderbare Typen enthalten, die nach ihrem Wert und nicht
nach ihrer Objektidentität verglichen werden. Der Grund dafür ist,
dass die effiziente Implementierung von Wörterbüchern erfordert, dass
der Hash-Wert eines Schlüssels konstant bleibt. Für Schlüssel
verwendete numerische Typen folgen den üblichen Regeln für den
numerischen Vergleich: Sind zwei Zahlen gleich (z. B. "1" und "1.0"),
können sie austauschbar zur Indizierung desselben Wörterbucheintrags
verwendet werden.

Wörterbücher behalten die Einfügungsreihenfolge bei, d.h., die
Schlüssel werden in derselben Reihenfolge ausgegeben, in der sie
nacheinander in das Wörterbuch eingefügt wurden. Das Ersetzen eines
vorhandenen Schlüssels ändert die Reihenfolge nicht; wird ein
Schlüssel jedoch entfernt und anschließend erneut eingefügt, wird er
am Ende angehängt, anstatt seinen ursprünglichen Platz beizubehalten.

Wörterbücher sind veränderbar. Du kannst mithilfe der Notation „ "{}"
“ erstellt werden (siehe Abschnitt „ Wörterbuchanzeigen “).

Die Erweiterungsmodule "dbm.ndbm" und "dbm.gnu" enthalten weitere
Beispiele für Zuordnungstypen, ebenso wie das Modul "collections".

Geändert in Version 3.7: In Python-Versionen vor 3.6 wurde die
Einfügereihenfolge in Dictionaries nicht beibehalten. In CPython 3.6
wurde die Einfügereihenfolge zwar beibehalten, dies galt damals jedoch
eher als Implementierungsdetail und nicht als sprachliche Garantie.


3.2.8. Aufrufbare Typen
-----------------------

Dies sind die Typen, auf die die Funktionsaufruf-Operation (siehe
Abschnitt „ Calls “) angewendet werden kann:


3.2.8.1. Benutzerdefinierte Funktionen
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Ein benutzerdefiniertes Funktionsobjekt wird durch eine
Funktionsdefinition erstellt (siehe Abschnitt „ Funktionsdefinitionen
“). Es sollte mit einer Argumentliste aufgerufen werden, die dieselbe
Anzahl von Elementen enthält wie die formale Parameterliste der
Funktion.


3.2.8.1.1. Besondere schreibgeschützte Attribute
""""""""""""""""""""""""""""""""""""""""""""""""

+----------------------------------------------------+----------------------------------------------------+
| Attribut                                           | Bedeutung                                          |
|====================================================|====================================================|
| function.__builtins__                              | Ein Verweis auf das "dictionary", das den          |
|                                                    | Namespace „builtins“ der Funktion enthält.  Added  |
|                                                    | in version 3.10.                                   |
+----------------------------------------------------+----------------------------------------------------+
| function.__globals__                               | Ein Verweis auf das "Wörterbuch", das die globalen |
|                                                    | Variablen der Funktion enthält – den globalen      |
|                                                    | Namensraum des Moduls, in dem die Funktion         |
|                                                    | definiert wurde.                                   |
+----------------------------------------------------+----------------------------------------------------+
| function.__closure__                               | "None" oder ein "tuple" aus Zellen, die Bindungen  |
|                                                    | für die Namen enthalten, die im Attribut           |
|                                                    | "co_freevars" des "code-Objekts der Funktion"      |
|                                                    | angegeben sind.  Ein Zellenobjekt verfügt über das |
|                                                    | Attribut „ "cell_contents" “. Damit lässt sich     |
|                                                    | sowohl der Wert der Zelle abrufen als auch der     |
|                                                    | Wert festlegen.                                    |
+----------------------------------------------------+----------------------------------------------------+


3.2.8.1.2. Besondere beschreibbare Attribute
""""""""""""""""""""""""""""""""""""""""""""

Die meisten dieser Attribute prüfen den Typ des zugewiesenen Werts:

+----------------------------------------------------+----------------------------------------------------+
| Attribut                                           | Bedeutung                                          |
|====================================================|====================================================|
| function.__doc__                                   | Die Dokumentationszeichenfolge der Funktion oder,  |
|                                                    | falls diese nicht vorhanden ist, "None".           |
+----------------------------------------------------+----------------------------------------------------+
| function.__name__                                  | Der Name der Funktion. Siehe auch:                 |
|                                                    | "__name__-Attribute".                              |
+----------------------------------------------------+----------------------------------------------------+
| function.__qualname__                              | Der *qualifizierte Name* der Funktion. Siehe auch: |
|                                                    | "__qualname__-Attribute".  Added in version 3.3.   |
+----------------------------------------------------+----------------------------------------------------+
| function.__module__                                | Der Name des Moduls, in dem die Funktion definiert |
|                                                    | wurde, oder „ "None" “, falls dieser nicht         |
|                                                    | verfügbar ist.                                     |
+----------------------------------------------------+----------------------------------------------------+
| function.__defaults__                              | Ein "tuple", das die Standardwerte für jene        |
|                                                    | *Parameter* enthält, die Standardwerte haben, oder |
|                                                    | "None", falls kein Parameter einen Standardwert    |
|                                                    | hat.                                               |
+----------------------------------------------------+----------------------------------------------------+
| function.__code__                                  | Das code-Objekt, das den kompilierten              |
|                                                    | Funktionskörper darstellt.                         |
+----------------------------------------------------+----------------------------------------------------+
| function.__dict__                                  | Der Namensraum, der beliebige Funktionsattribute   |
|                                                    | unterstützt. Siehe auch: "__dict__-Attribute".     |
+----------------------------------------------------+----------------------------------------------------+
| function.__annotations__                           | A "dictionary" containing annotations of           |
|                                                    | *parameters*. The keys of the dictionary are the   |
|                                                    | parameter names, and "'return'" for the return     |
|                                                    | annotation, if provided. See also: Annotations     |
|                                                    | Best Practices.                                    |
+----------------------------------------------------+----------------------------------------------------+
| function.__kwdefaults__                            | Ein "Wörterbuch", das Standardwerte für *Parameter |
|                                                    | enthält, die nur über Schlüsselwörter aufgerufen   |
|                                                    | werden können*.                                    |
+----------------------------------------------------+----------------------------------------------------+
| function.__type_params__                           | Ein ` "tuple" *, der die :ref:`Typ-Parameter       |
|                                                    | <type-params>* einer generischen Funktion enthält. |
|                                                    | Added in version 3.12.                             |
+----------------------------------------------------+----------------------------------------------------+

Funktionsobjekte unterstützen zudem das Abrufen und Setzen beliebiger
Attribute, was beispielsweise dazu genutzt werden kann, Funktionen
Metadaten hinzuzufügen. Zum Abrufen und Setzen solcher Attribute wird
die übliche Punktnotation verwendet.

Die aktuelle Implementierung von CPython unterstützt
Funktionsattribute nur für benutzerdefinierte Funktionen.
Funktionsattribute für eingebaute Funktionen werden möglicherweise in
Zukunft unterstützt.

Weitere Informationen zur Definition einer Funktion können aus ihrem
Code-Objekt abgerufen werden (zugänglich über das Attribut "__code__"
).


3.2.8.2. Instanzmethoden
~~~~~~~~~~~~~~~~~~~~~~~~

Ein Instanzmethodenobjekt verbindet eine Klasse, eine Klasseninstanz
und ein beliebiges aufrufbares Objekt (in der Regel eine
benutzerdefinierte Funktion).

Besondere schreibgeschützte Attribute:

+----------------------------------------------------+----------------------------------------------------+
| method.__self__                                    | Bezieht sich auf das Klasseninstanzobjekt, an das  |
|                                                    | die Methode gebunden ist <method-binding>`         |
+----------------------------------------------------+----------------------------------------------------+
| method.__func__                                    | Bezieht sich auf das ursprüngliche Funktionsobjekt |
+----------------------------------------------------+----------------------------------------------------+
| method.__doc__                                     | Die Dokumentation der Methode (entspricht          |
|                                                    | "method.__func__.__doc__"). Ein "string", falls    |
|                                                    | die ursprüngliche Funktion einen Docstring hatte,  |
|                                                    | andernfalls "None".                                |
+----------------------------------------------------+----------------------------------------------------+
| method.__name__                                    | Der Name der Methode (entspricht                   |
|                                                    | "method.__func__.__name__")                        |
+----------------------------------------------------+----------------------------------------------------+
| method.__module__                                  | Der Name des Moduls, in dem die Methode definiert  |
|                                                    | wurde, oder „ "None" “, falls dieser nicht         |
|                                                    | verfügbar ist.                                     |
+----------------------------------------------------+----------------------------------------------------+

Die Methoden unterstützen außerdem den Zugriff (jedoch nicht das
Setzen) auf die beliebigen Funktionsattribute des zugrunde liegenden
Funktionsobjekts.

Benutzerdefinierte Methodenobjekte können beim Abrufen eines Attributs
einer Klasse (möglicherweise über eine Instanz dieser Klasse) erstellt
werden, wenn es sich bei diesem Attribut um ein benutzerdefiniertes
Funktionsobjekt oder ein "classmethod" -Objekt handelt.

Wenn ein Instanzmethodenobjekt erstellt wird, indem ein
benutzerdefiniertes Funktionsobjekt über eine der Instanzen einer
Klasse abgerufen wird, ist sein Attribut „ "__self__" “ die Instanz,
und das Methodenobjekt gilt als *gebunden*. Das Attribut „ "__func__"
“ der neuen Methode ist das ursprüngliche Funktionsobjekt.

Wenn ein Instanzmethodenobjekt durch das Abrufen eines „ "classmethod"
“-Objekts aus einer Klasse oder Instanz erstellt wird, ist sein
Attribut „ "__self__" “ die Klasse selbst, und sein Attribut „
"__func__" “ ist das Funktionsobjekt, das der Klassenmethode zugrunde
liegt.

Wenn ein Instanzmethodenobjekt aufgerufen wird, wird die zugrunde
liegende Funktion ("__func__") aufgerufen, wobei die Klasseninstanz
("__self__") vor die Argumentliste eingefügt wird. Wenn beispielsweise
"C" eine Klasse ist, die eine Definition für die Funktion "f()"
enthält, und "x" eine Instanz von "C" ist, entspricht der Aufruf von
"x.f(1)" dem Aufruf von "C.f(x, 1)".

Wenn ein Instanzmethodenobjekt von einem „ "classmethod" “-Objekt
abgeleitet ist, ist die in ` "__self__" ` gespeicherte
„Klasseninstanz“ tatsächlich die Klasse selbst, sodass der Aufruf von
entweder ` "x.f(1)" ` oder ` "C.f(1)" ` dem Aufruf von ` "f(C,1)" `
entspricht, wobei ` "f" ` die zugrunde liegende Funktion ist.

Es ist wichtig zu beachten, dass benutzerdefinierte Funktionen, die
Attribute einer Klasseninstanz sind, nicht in gebundene Methoden
umgewandelt werden; dies geschieht *nur*, wenn die Funktion ein
Attribut der Klasse ist.


3.2.8.3. Generatorfunktionen
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A function or method which contains a "yield" expression (see section
Yield Ausdrücke) is called a *generator function*.  Such a function,
when called, always returns an *iterator* object which can be used to
execute the body of the function:  calling the iterator's
"iterator.__next__()" method will cause the function to execute until
it provides a value using the "yield" expression.  When the function
executes a "return" statement or falls off the end, a "StopIteration"
exception is raised and the iterator will have reached the end of the
set of values to be returned.


3.2.8.4. Coroutinen-Funktionen
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Eine Funktion oder Methode, die mit "async def" definiert wird, wird
als *Coroutine-Funktion* bezeichnet.  Eine solche Funktion gibt bei
ihrem Aufruf ein *Coroutine*-Objekt zurück. Sie kann "await"
-Ausdrücke sowie "async with"- und "async for"-Anweisungen enthalten.
Siehe auch den Abschnitt „ Coroutinen-Objekte “.


3.2.8.5. Asynchrone Generatorfunktionen
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A function or method which is defined using "async def" and which
contains a "yield" expression is called a *asynchronous generator
function*.  Such a function, when called, returns an *asynchronous
iterator* object which can be used in an "async for" statement to
execute the body of the function.

Der Aufruf der Methode "aiterator.__anext__" des asynchronen Iterators
gibt ein *awaitable* zurück, das bei der Abfrage so lange ausgeführt
wird, bis es mithilfe des Ausdrucks "yield" einen Wert liefert.  Wenn
die Funktion eine leere "return" -Anweisung ausführt oder das Ende der
Wertefolge erreicht, wird eine "StopAsyncIteration" -Ausnahme
ausgelöst, und der asynchrone Iterator hat das Ende der zu liefernden
Wertefolge erreicht.


3.2.8.6. Integrierte Funktionen
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Ein integriertes Funktionsobjekt ist eine Hülle um eine C-Funktion.
Beispiele für integrierte Funktionen sind "len()" und "math.sin()"
("math" ist ein standardmäßiges integriertes Modul). Die Anzahl und
der Typ der Argumente werden durch die C-Funktion bestimmt. Spezielle
schreibgeschützte Attribute:

* "__doc__" ist die Dokumentationszeichenfolge der Funktion oder,
  falls diese nicht vorhanden ist, „ "None" “. Siehe
  "function.__doc__".

* "__name__" ist der Name der Funktion. Siehe "function.__name__".

* "__self__" ist auf „ "None" “ eingestellt (siehe jedoch den nächsten
  Punkt).

* "__module__" ist der Name des Moduls, in dem die Funktion definiert
  wurde, oder „ "None" “, falls dieser nicht verfügbar ist. Siehe
  "function.__module__".


3.2.8.7. Integrierte Methoden
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Hier handelt es sich eigentlich um eine andere Form einer integrierten
Funktion, die diesmal ein Objekt enthält, das als implizites
zusätzliches Argument an die C-Funktion übergeben wird. Ein Beispiel
für eine integrierte Methode ist ` "alist.append()`", vorausgesetzt,
*alist* ist ein Listenobjekt. In diesem Fall wird das spezielle,
schreibgeschützte Attribut "__self__" auf das durch *alist*
bezeichnete Objekt gesetzt. (Das Attribut hat dieselbe Semantik wie
bei "anderen Instanzmethoden".)


3.2.8.8. Kurse
~~~~~~~~~~~~~~

Klassen sind aufrufbar. Diese Objekte fungieren normalerweise als
Fabriken für neue Instanzen ihrer selbst, doch bei Klassentypen, die
"__new__()" überschreiben, sind Abweichungen möglich. Die Argumente
des Aufrufs werden an "__new__()" und im typischen Fall an
"__init__()" übergeben, um die neue Instanz zu initialisieren.


3.2.8.9. Klasseninstanzen
~~~~~~~~~~~~~~~~~~~~~~~~~

Instanzen beliebiger Klassen können aufrufbar gemacht werden, indem in
ihrer Klasse eine Methode „ "__call__()" “ definiert wird.


3.2.9. Module
-------------

Module sind eine grundlegende Organisationseinheit von Python-Code und
werden durch das Import-System erstellt, das entweder durch die
Anweisung "import" oder durch den Aufruf von Funktionen wie
"importlib.import_module()" und der integrierten Funktion
"__import__()" aufgerufen wird.  Ein Modulobjekt verfügt über einen
Namensraum, der durch ein "dictionary" -Objekt implementiert wird
(dies ist das Wörterbuch, auf das das Attribut "__globals__" von im
Modul definierten Funktionen verweist).  Attributverweise werden in
Suchvorgänge in diesem Wörterbuch übersetzt, z. B. entspricht ` "m.x"
` dem Ausdruck ` "m.__dict__["x"]`". Ein Modulobjekt enthält nicht das
Code-Objekt, das zur Initialisierung des Moduls verwendet wurde (da es
nach Abschluss der Initialisierung nicht mehr benötigt wird).

Durch die Zuweisung von Attributen wird das Namensraum-Wörterbuch des
Moduls aktualisiert; so entspricht beispielsweise ` "m.x = 1" ` dem
Ausdruck ` "m.__dict__["x"] = 1`".


3.2.9.1. Importbezogene Attribute von Modulobjekten
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Modulobjekte verfügen über die folgenden Attribute, die sich auf das
Import-System beziehen. Wenn ein Modul mithilfe der zum Import-System
gehörenden Mechanismen erstellt wird, werden diese Attribute auf der
Grundlage der *Spezifikation* des Moduls ausgefüllt, bevor der
*Loader* ausgeführt wird und das Modul lädt.

Um ein Modul dynamisch zu erstellen, anstatt das Import-System zu
verwenden, empfiehlt es sich, "importlib.util.module_from_spec()" zu
nutzen, wodurch die verschiedenen importgesteuerten Attribute auf die
entsprechenden Werte gesetzt werden. Es ist auch möglich, Module
direkt mit dem Konstruktor "types.ModuleType" zu erstellen, doch diese
Vorgehensweise ist fehleranfälliger, da bei diesem Ansatz die meisten
Attribute nach der Erstellung des Modulobjekts manuell gesetzt werden
müssen.

Vorsicht:

  Mit Ausnahme von "__name__" wird **dringend** empfohlen, stattdessen
  auf "__spec__" und dessen Attribute zurückzugreifen, anstatt auf
  eines der anderen in diesem Unterabschnitt aufgeführten
  Einzelattribute. Beachten Sie, dass die Aktualisierung eines
  Attributs unter "__spec__" nicht zur Aktualisierung des
  entsprechenden Attributs im Modul selbst führt:

     >>> import typing
     >>> typing.__name__, typing.__spec__.name
     ('typing', 'typing')
     >>> typing.__spec__.name = 'spelling'
     >>> typing.__name__, typing.__spec__.name
     ('typing', 'spelling')
     >>> typing.__name__ = 'keyboard_smashing'
     >>> typing.__name__, typing.__spec__.name
     ('keyboard_smashing', 'spelling')

module.__name__

   Der Name, der zur eindeutigen Identifizierung des Moduls im Import-
   System verwendet wird. Bei einem direkt ausgeführten Modul wird
   dieser auf „ ""__main__"" “ gesetzt.

   Dieses Attribut muss auf den vollqualifizierten Namen des Moduls
   gesetzt werden. Es sollte mit dem Wert von "module.__spec__.name"
   übereinstimmen.

module.__spec__

   Eine Aufzeichnung des Zustands des Moduls in Bezug auf das
   Importsystem.

   Wird auf die "Modul-Spezifikation" gesetzt, die beim Importieren
   des Moduls verwendet wurde. Weitere Informationen findest du unter
   Modulspezifikationen.

   Added in version 3.4.

module.__package__

   Das *Paket*, zu dem ein Modul gehört.

   Wenn es sich um ein Modul der obersten Ebene handelt (das heißt,
   das nicht Teil eines bestimmten Pakets ist), sollte das Attribut
   auf „ "''" “ (die leere Zeichenkette) gesetzt werden. Andernfalls
   sollte es auf den Namen des Pakets des Moduls gesetzt werden (der
   mit „ "module.__name__" “ übereinstimmen kann, wenn das Modul
   selbst ein Paket ist). Weitere Einzelheiten findest du unter **PEP
   366**.

   Dieses Attribut wird anstelle von „ "__name__" “ verwendet, um
   explizite relative Importe für Hauptmodule zu berechnen. Der
   Standardwert lautet „ "None" “ für Module, die dynamisch mit dem
   Konstruktor „ "types.ModuleType" “ erstellt wurden; verwende
   stattdessen „ "importlib.util.module_from_spec()" “, um
   sicherzustellen, dass das Attribut auf „ "str" “ gesetzt ist.

   Es wird **dringend** empfohlen, anstelle von "module.__package__"
   die Syntax "module.__spec__.parent" zu verwenden. "__package__"
   wird nun nur noch als Ausweichmöglichkeit verwendet, wenn
   "__spec__.parent" nicht gesetzt ist, und dieser Ausweichpfad ist
   veraltet.

   Geändert in Version 3.4: Dieses Attribut ist nun standardmäßig auf
   „ "None" “ gesetzt für Module, die dynamisch mithilfe des
   Konstruktors „ "types.ModuleType" “ erstellt werden. Zuvor war das
   Attribut optional.

   Geändert in Version 3.6: Der Wert von "__package__" sollte mit dem
   von "__spec__.parent" übereinstimmen. "__package__" wird nun nur
   noch als Ausweichlösung bei der Import-Auflösung verwendet, wenn
   "__spec__.parent" nicht definiert ist.

   Geändert in Version 3.10: Ein "ImportWarning" wird ausgelöst, wenn
   eine Importauflösung auf "__package__" zurückfällt statt auf
   "__spec__.parent".

   Geändert in Version 3.12: Löst bei der Umleitung auf "__package__"
   während der Importauflösung eine „ "DeprecationWarning" “-Ausnahme
   anstelle einer „ "ImportWarning" “-Ausnahme aus.

   Veraltet seit Version 3.13, wird in Version 3.15 entfernt:
   "__package__" wird vom Importsystem oder der Standardbibliothek
   nicht mehr gesetzt oder berücksichtigt.

module.__loader__

   Das *loader*-Objekt, das vom Importmechanismus zum Laden des Moduls
   verwendet wurde.

   Dieses Attribut ist vor allem für die Introspektion nützlich, kann
   aber auch für zusätzliche, laderspezifische Funktionen genutzt
   werden, beispielsweise zum Abrufen von Daten, die mit einem Lader
   verknüpft sind.

   "__loader__" Standardmäßig ist der Wert „ "None" “ für Module, die
   dynamisch mit dem Konstruktor „ "types.ModuleType" “ erstellt
   wurden; verwende stattdessen „ "importlib.util.module_from_spec()"
   “, um sicherzustellen, dass das Attribut auf ein *loader*-Objekt
   gesetzt wird.

   Es wird **dringend** empfohlen, anstelle von „ "module.__loader__"
   “ die Anweisung „"module.__spec__.loader" “ zu verwenden.

   Geändert in Version 3.4: Dieses Attribut ist nun standardmäßig auf
   „ "None" “ gesetzt für Module, die dynamisch mithilfe des
   Konstruktors „ "types.ModuleType" “ erstellt werden. Zuvor war das
   Attribut optional.

   Veraltet seit Version 3.12, wird in Version 3.16 entfernt: Das
   Setzen von „ "__loader__" “ für ein Modul, ohne gleichzeitig „
   "__spec__.loader" “ zu setzen, ist veraltet. Ab Python 3.16 wird „
   "__loader__" “ vom Import-System und von der Standardbibliothek
   nicht mehr gesetzt oder berücksichtigt.

module.__path__

   Eine (möglicherweise leere) *Sequenz* von Zeichenketten, die die
   Speicherorte auflistet, an denen die Submodule des Pakets zu finden
   sind. Module, die nicht zum Paket gehören, sollten kein Attribut „
   "__path__" “ haben. Weitere Informationen findest du unter
   __path__-Attribute in Modulen.

   Es wird **dringend** empfohlen,
   "module.__spec__.submodule_search_locations" anstelle von
   "module.__path__" zu verwenden.

module.__file__

module.__cached__

   "__file__" und „ "__cached__" “ sind beides optionale Attribute,
   die gesetzt werden können, aber nicht müssen. Beide Attribute
   sollten den Wert „ "str" “ haben, sofern sie verfügbar sind.

   "__file__" Gibt den Pfadnamen der Datei an, aus der das Modul
   geladen wurde (sofern es aus einer Datei geladen wurde), oder den
   Pfadnamen der gemeinsam genutzten Bibliotheksdatei für
   Erweiterungsmodule, die dynamisch aus einer gemeinsam genutzten
   Bibliothek geladen wurden. Bei bestimmten Modultypen, wie z. B.
   C-Modulen, die statisch in den Interpreter eingebunden sind, kann
   dieser Wert fehlen, und das Import-System kann ihn bewusst
   ungesetzt lassen, wenn er keine semantische Bedeutung hat (z. B.
   bei einem aus einer Datenbank geladenen Modul).

   Wenn „ "__file__" “ gesetzt ist, kann auch das Attribut „
   "__cached__" “ gesetzt sein, das den Pfad zu einer beliebigen
   kompilierten Version des Codes angibt (beispielsweise eine byte-
   kompilierte Datei). Die Datei muss nicht vorhanden sein, um dieses
   Attribut zu setzen; der Pfad kann einfach auf den Ort verweisen, an
   dem die kompilierte Datei *vorhanden wäre* (siehe **PEP 3147**).

   Beachten Sie, dass „ "__cached__" “ auch dann gesetzt sein kann,
   wenn „ "__file__" “ nicht gesetzt ist. Dieses Szenario ist jedoch
   eher untypisch.  Letztendlich ist es der *loader*, der die vom
   *finder* bereitgestellte Modulspezifikation nutzt (aus der sich
   "__file__" und "__cached__" ableiten).  Wenn also ein Loader aus
   einem zwischengespeicherten Modul laden kann, aber ansonsten nicht
   aus einer Datei lädt, könnte dieses untypische Szenario durchaus
   angemessen sein.

   Es wird **dringend** empfohlen, "module.__spec__.cached" anstelle
   von "module.__cached__" zu verwenden.

   Veraltet seit Version 3.13, wird in Version 3.15 entfernt: Das
   Setzen von „ "__cached__" “ für ein Modul, ohne gleichzeitig „
   "__spec__.cached" “ zu setzen, ist veraltet. Ab Python 3.15 wird „
   "__cached__" “ nicht mehr gesetzt und vom Import-System oder der
   Standardbibliothek nicht mehr berücksichtigt.


3.2.9.2. Weitere beschreibbare Attribute von Modulobjekten
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Neben den oben aufgeführten importbezogenen Attributen verfügen
Modulobjekte außerdem über die folgenden beschreibbaren Attribute:

module.__doc__

   Die Dokumentationszeichenfolge des Moduls oder, falls nicht
   vorhanden, ` "None" *. Siehe auch: :attr:`__doc__-Attribute
   <definition.__doc__>*.

module.__annotations__

   A dictionary containing *variable annotations* collected during
   module body execution.  For best practices on working with
   "__annotations__", please see Annotations Best Practices.


3.2.9.3. Modulwörterbücher
~~~~~~~~~~~~~~~~~~~~~~~~~~

Modulobjekte verfügen außerdem über das folgende spezielle
schreibgeschützte Attribut:

module.__dict__

   Der Namensraum des Moduls als Wörterbuchobjekt. Als einziges der
   hier aufgeführten Attribute kann auf „ "__dict__" “ nicht als
   globale Variable aus einem Modul heraus zugegriffen werden; der
   Zugriff ist nur als Attribut von Modulobjekten möglich.

   Aufgrund der Art und Weise, wie CPython Modul-Dictionaries löscht,
   wird das Modul-Dictionary gelöscht, sobald das Modul den
   Gültigkeitsbereich verlässt – selbst wenn das Dictionary noch
   aktive Verweise enthält. Um dies zu vermeiden, kopiere das
   Dictionary oder behalte das Modul bei, während du dessen Dictionary
   direkt verwenden.


3.2.10. Benutzerdefinierte Klassen
----------------------------------

Eigene Klassentypen werden üblicherweise durch Klassendefinitionen
erzeugt (siehe Abschnitt Klassendefinitionen). Eine Klasse hat einen
Namensraum, der durch ein Dictionary-Objekt umgesetzt ist. Verweise
auf Klassenattribute werden in Nachschlagevorgänge in diesem
Dictionary übersetzt, beispielsweise wird "C.x" zu "C.__dict__["x"]"
(es gibt allerdings eine Reihe von Hooks, die andere Wege zum
Auffinden von Attributen erlauben). Wird der Attributname dort nicht
gefunden, setzt sich die Suche in den Basisklassen fort. Diese Suche
verwendet die C3-Methodenauflösungsreihenfolge, die auch bei
rautenförmigen Vererbungsstrukturen korrekt arbeitet, bei denen
mehrere Vererbungspfade zu einem gemeinsamen Vorfahren zurückführen.
Weitere Einzelheiten zur von Python verwendeten C3-MRO findest du
unter The Python 2.3 Method Resolution Order.

Wenn eine Klassenattributreferenz (beispielsweise für die Klasse „ "C"
“) ein Klassenmethodenobjekt liefern würde, wird sie in ein
Instanzmethodenobjekt umgewandelt, dessen Attribut „ "__self__" “ den
Wert „ "C" “ annimmt. Wenn sie ein „ "staticmethod" “-Objekt liefern
würde, wird sie in das Objekt umgewandelt, das vom statischen
Methodenobjekt umschlossen wird. Im Abschnitt „ Implementierung von
Deskriptoren “ wird eine weitere Möglichkeit beschrieben, wie sich aus
einer Klasse abgerufene Attribute von denen unterscheiden können, die
tatsächlich in deren „ "__dict__" “ enthalten sind.

Durch die Zuweisung von Klassenattributen wird das Wörterbuch der
Klasse aktualisiert, niemals jedoch das Wörterbuch einer Basisklasse.

Ein Klassenobjekt kann aufgerufen werden (siehe oben), um eine
Klasseninstanz zu erzeugen (siehe unten).


3.2.10.1. Besondere Eigenschaften
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+----------------------------------------------------+----------------------------------------------------+
| Attribut                                           | Bedeutung                                          |
|====================================================|====================================================|
| type.__name__                                      | Der Name der Klasse. Siehe auch:                   |
|                                                    | "__name__-Attribute".                              |
+----------------------------------------------------+----------------------------------------------------+
| type.__qualname__                                  | Der *qualifizierte Name* der Klasse. Siehe auch:   |
|                                                    | "__qualname__-Attribute".                          |
+----------------------------------------------------+----------------------------------------------------+
| type.__module__                                    | Der Name des Moduls, in dem die Klasse definiert   |
|                                                    | wurde.                                             |
+----------------------------------------------------+----------------------------------------------------+
| type.__dict__                                      | Ein "Mapping-Proxy", der eine schreibgeschützte    |
|                                                    | Ansicht des Namensraums der Klasse bereitstellt.   |
|                                                    | Siehe auch: "__dict__-Attribute".                  |
+----------------------------------------------------+----------------------------------------------------+
| type.__bases__                                     | Ein ` "tuple" *, der die Basisklassen der Klasse   |
|                                                    | enthält. In den meisten Fällen gilt für eine       |
|                                                    | Klasse, die wie folgt definiert ist: ` ``class     |
|                                                    | X(A, B, C)``*, dass ` "X.__bases__" ` genau gleich |
|                                                    | ` "(A, B, C)`" ist.                                |
+----------------------------------------------------+----------------------------------------------------+
| type.__base__                                      | Die einzige Basisklasse in der Vererbungskette,    |
|                                                    | die für die Speicheranordnung der Instanzen        |
|                                                    | verantwortlich ist. Dieses Attribut entspricht auf |
|                                                    | C-Ebene dem „ "tp_base" “.                         |
+----------------------------------------------------+----------------------------------------------------+
| type.__doc__                                       | Der Dokumentationsstring der Klasse oder „ "None"  |
|                                                    | “, falls nicht definiert. Wird nicht an            |
|                                                    | Unterklassen vererbt.                              |
+----------------------------------------------------+----------------------------------------------------+
| type.__annotations__                               | A dictionary containing *variable annotations*     |
|                                                    | collected during class body execution. For best    |
|                                                    | practices on working with "__annotations__",       |
|                                                    | please see Annotations Best Practices.  Vorsicht:  |
|                                                    | Accessing the "__annotations__" attribute of a     |
|                                                    | class object directly may yield incorrect results  |
|                                                    | in the presence of metaclasses. In addition, the   |
|                                                    | attribute may not exist for some classes. Use      |
|                                                    | "inspect.get_annotations()" to retrieve class      |
|                                                    | annotations safely.                                |
+----------------------------------------------------+----------------------------------------------------+
| type.__type_params__                               | Ein ` "tuple" *, der die :ref:`Typ-Parameter       |
|                                                    | <type-params>* einer generischen Klasse enthält.   |
|                                                    | Added in version 3.12.                             |
+----------------------------------------------------+----------------------------------------------------+
| type.__static_attributes__                         | Ein ` "tuple" *, der die Namen der Attribute       |
|                                                    | dieser Klasse enthält, die über ` ``self.X`* ` von |
|                                                    | einer beliebigen Funktion in ihrem Körper          |
|                                                    | zugewiesen werden.  Added in version 3.13.         |
+----------------------------------------------------+----------------------------------------------------+
| type.__firstlineno__                               | Die Zeilennummer der ersten Zeile der              |
|                                                    | Klassendefinition, einschließlich Dekoratoren.     |
|                                                    | Durch das Setzen des Attributs „ "__module__" “    |
|                                                    | wird der Eintrag „ "__firstlineno__" “ aus dem     |
|                                                    | Wörterbuch des Typs entfernt.  Added in version    |
|                                                    | 3.13.                                              |
+----------------------------------------------------+----------------------------------------------------+
| type.__mro__                                       | Die „ "tuple" “ der Klassen, die bei der Suche     |
|                                                    | nach Basisklassen während der Methodenauflösung    |
|                                                    | berücksichtigt werden.                             |
+----------------------------------------------------+----------------------------------------------------+


3.2.10.2. Spezielle Methoden
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Zusätzlich zu den oben beschriebenen speziellen Eigenschaften stehen
für alle Python-Klassen außerdem die folgenden beiden Methoden zur
Verfügung:

type.mro()

   Diese Methode kann von einer Metaklasse überschrieben werden, um
   die Reihenfolge der Methodenauflösung für ihre Instanzen
   anzupassen. Sie wird bei der Instanziierung der Klasse aufgerufen,
   und ihr Ergebnis wird in "__mro__" gespeichert.

type.__subclasses__()

   Jede Klasse führt eine Liste mit schwachen Referenzen auf ihre
   unmittelbaren Unterklassen. Diese Methode gibt eine Liste aller
   noch bestehenden Referenzen zurück. Die Liste ist in der
   Reihenfolge der Definitionen sortiert. Beispiel:

      >>> Klasse A: pass
      >>> Klasse B(A): pass
      >>> A.__subclasses__()
      [<class 'B'>]


3.2.11. Klasseninstanzen
------------------------

Eine Klasseninstanz wird durch den Aufruf eines Klassenobjekts
erstellt (siehe oben). Eine Klasseninstanz verfügt über einen
Namensraum, der als Wörterbuch implementiert ist und in dem zunächst
nach Attributreferenzen gesucht wird. Wird ein Attribut dort nicht
gefunden und verfügt die Klasse der Instanz über ein Attribut mit
diesem Namen, wird die Suche mit den Klassenattributen fortgesetzt.
Wird ein Klassenattribut gefunden, das ein benutzerdefiniertes
Funktionsobjekt ist, wird es in ein Instanzmethodenobjekt umgewandelt,
dessen Attribut "__self__" die Instanz ist. Statische Methoden- und
Klassenmethodenobjekte werden ebenfalls umgewandelt; siehe oben unter
„Klassen“.  Im Abschnitt Implementierung von Deskriptoren wird eine
weitere Möglichkeit beschrieben, in der sich Attribute einer Klasse,
die über ihre Instanzen abgerufen werden, von den tatsächlich im
"__dict__" der Klasse gespeicherten Objekten unterscheiden können.
Wird kein Klassenattribut gefunden und verfügt die Klasse des Objekts
über eine "__getattr__()"-Methode, wird diese aufgerufen, um die Suche
durchzuführen.

Durch das Zuweisen und Löschen von Attributen wird das Wörterbuch der
Instanz aktualisiert, niemals das Wörterbuch einer Klasse. Verfügt die
Klasse über eine Methode „ "__setattr__()" “ oder „ "__delattr__()" “,
wird diese aufgerufen, anstatt das Instanzwörterbuch direkt zu
aktualisieren.

Klasseninstanzen können sich als Zahlen, Sequenzen oder Abbildungen
ausgeben, wenn sie Methoden mit bestimmten speziellen Namen besitzen.
Siehe Abschnitt „ Spezielle Methodennamen “.


3.2.11.1. Besondere Eigenschaften
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

object.__class__

   Die Klasse, zu der eine Klasseninstanz gehört.

object.__dict__

   Ein Wörterbuch oder ein anderes Zuordnungsobjekt, das zum Speichern
   der (beschreibbaren) Attribute eines Objekts verwendet wird. Nicht
   alle Instanzen verfügen über ein „ "__dict__" “-Attribut; weitere
   Informationen findest du im Abschnitt „ __slots__ “.


3.2.12. E/A-Objekte (auch als Datei-Objekte bezeichnet)
-------------------------------------------------------

Ein *Dateiobjekt* stellt eine geöffnete Datei dar. Es stehen
verschiedene Möglichkeiten zur Verfügung, um Dateiobjekte zu
erstellen: die integrierte Funktion „ "open()" “ sowie „ "os.popen()"
“, „ "os.fdopen()" “ und die Methode „ "makefile()" “ von Socket-
Objekten (und möglicherweise auch andere Funktionen oder Methoden, die
von Erweiterungsmodulen bereitgestellt werden).

Dateiobjekte implementieren die unten aufgeführten allgemeinen
Methoden, um die Verwendung in generischem Code zu vereinfachen. Es
wird erwartet, dass sie „ Mit Statement-Kontextmanagern “ sind.

Die Objekte „ "sys.stdin" “, „ "sys.stdout" “ und „ "sys.stderr" “
werden als Dateiobjekte initialisiert, die den Standard-Eingabe-,
-Ausgabe- und -Fehlerströmen des Interpreters entsprechen. Sie sind
alle im Textmodus geöffnet und folgen daher der durch die abstrakte
Klasse „ "io.TextIOBase" “ definierten Schnittstelle.

file.read(size=-1, /)

   Lade bis zu *size* Daten aus der Datei. Wenn *size* nicht angegeben
   ist oder den Wert -1 hat, werden der Einfachheit halber alle
   verfügbaren Daten geladen.

file.write(data, /)

   *Daten* in der Datei speichern.

file.close()

   Alle Puffer leeren und die zugrunde liegende Datei schließen.


3.2.13. Interne Typen
---------------------

Einige vom Interpreter intern verwendete Typen stehen dem Benutzer zur
Verfügung. Ihre Definitionen können sich in zukünftigen Versionen des
Interpreter ändern, werden hier jedoch der Vollständigkeit halber
aufgeführt.


3.2.13.1. Code-Objekte
~~~~~~~~~~~~~~~~~~~~~~

Code-Objekte stellen *byte-kompilierten* ausführbaren Python-Code dar,
auch bekannt als *Bytecode*. Der Unterschied zwischen einem Codeobjekt
und einem Funktionsobjekt besteht darin, dass das Funktionsobjekt
einen expliziten Verweis auf die globalen Variablen der Funktion (das
Modul, in dem sie definiert wurde) enthält, während ein Codeobjekt
keinen Kontext enthält; außerdem werden die Standardwerte der
Argumente im Funktionsobjekt gespeichert, nicht im Codeobjekt (da sie
Werte darstellen, die zur Laufzeit berechnet werden).  Im Gegensatz zu
Funktionsobjekten sind Codeobjekte unveränderlich und enthalten keine
(direkten oder indirekten) Verweise auf veränderbare Objekte.


3.2.13.1.1. Besondere schreibgeschützte Attribute
"""""""""""""""""""""""""""""""""""""""""""""""""

+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_name                                 | Der Funktionsname                                  |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_qualname                             | Der vollqualifizierte Funktionsname  Added in      |
|                                                    | version 3.11.                                      |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_argcount                             | Die Gesamtzahl der positionellen *Parameter*       |
|                                                    | (einschließlich rein positioneller Parameter und   |
|                                                    | Parameter mit Standardwerten), über die die        |
|                                                    | Funktion verfügt                                   |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_posonlyargcount                      | Die Anzahl der rein positionellen *Parameter*      |
|                                                    | (einschließlich Argumente mit Standardwerten),     |
|                                                    | über die die Funktion verfügt                      |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_kwonlyargcount                       | Die Anzahl der reinen Schlüsselwort-Parameter      |
|                                                    | :term:` <parameter>` (einschließlich Argumente mit |
|                                                    | Standardwerten), über die die Funktion verfügt     |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_nlocals                              | Die Anzahl der von der Funktion verwendeten        |
|                                                    | lokalen Variablen (einschließlich Parameter)       |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_varnames                             | Ein "tuple", der die Namen der lokalen Variablen   |
|                                                    | in der Funktion enthält (beginnend mit den         |
|                                                    | Parameternamen)                                    |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_cellvars                             | Ein ` "tuple" *, der die Namen der :ref:`lokalen   |
|                                                    | Variablen <naming>* enthält, auf die von           |
|                                                    | mindestens einem *verschachtelten                  |
|                                                    | Gültigkeitsbereich* innerhalb der Funktion         |
|                                                    | verwiesen wird                                     |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_freevars                             | Ein "tuple", das die Namen der *freien             |
|                                                    | (Closure-)Variablen* enthält, auf die ein          |
|                                                    | *verschachtelter Gültigkeitsbereich* in einem      |
|                                                    | äußeren Gültigkeitsbereich verweist. Siehe auch    |
|                                                    | "function.__closure__".  Hinweis: Verweise auf     |
|                                                    | globale und integrierte Namen sind *nicht*         |
|                                                    | enthalten.                                         |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_code                                 | Eine Zeichenkette, die die Abfolge der             |
|                                                    | *Bytecode*-Befehle in der Funktion darstellt       |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_consts                               | Ein ` "tuple" *, der die vom :term:`Bytecode       |
|                                                    | <bytecode>* in der Funktion verwendeten Literale   |
|                                                    | enthält                                            |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_names                                | Ein ` "tuple" *, der die Namen enthält, die vom    |
|                                                    | :term:`Bytecode <bytecode>* in der Funktion        |
|                                                    | verwendet werden                                   |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_filename                             | Der Name der Datei, aus der der Code kompiliert    |
|                                                    | wurde                                              |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_firstlineno                          | Die Zeilennummer der ersten Zeile der Funktion     |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_lnotab                               | Eine Zeichenkette, die die Zuordnung von           |
|                                                    | *Bytecode*-Offsets zu Zeilennummern kodiert.       |
|                                                    | Einzelheiten findest du im Quellcode des           |
|                                                    | Interpreters.  Veraltet ab Version 3.12: Dieses    |
|                                                    | Attribut von Code-Objekten ist veraltet und wird   |
|                                                    | möglicherweise in Python 3.15 entfernt.            |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_stacksize                            | Die erforderliche Stackgröße des Code-Objekts      |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_flags                                | Eine "integer-", die eine Reihe von Flags für den  |
|                                                    | Interpreter kodiert.                               |
+----------------------------------------------------+----------------------------------------------------+

Für "co_flags" sind die folgenden Flag-Bits definiert: Das Bit "0x04"
ist gesetzt, wenn die Funktion die Syntax "*arguments" verwendet, um
eine beliebige Anzahl von Positionsargumenten zu akzeptieren Das Bit
"0x08" ist gesetzt, wenn die Funktion die Syntax "**keywords"
verwendet, um beliebige Schlüsselwortargumente zu akzeptieren. Das Bit
"0x20" ist gesetzt, wenn die Funktion ein Generator ist. Weitere
Informationen zur Semantik der einzelnen möglicherweise vorhandenen
Flags findest du unter Code Objects Bit Flags.

Auch Deklarationen zukünftiger Funktionen (zum Beispiel "from
__future__ import division") nutzen Bits in "co_flags", um anzugeben,
ob ein Codeobjekt mit einer bestimmten Funktion kompiliert wurde.
Siehe "compiler_flag".

Die übrigen Bits in „ "co_flags" “ sind für den internen Gebrauch
reserviert.

If a code object represents a function, the first item in "co_consts"
is the documentation string of the function, or "None" if undefined.


3.2.13.1.2. Methoden für Code-Objekte
"""""""""""""""""""""""""""""""""""""

codeobject.co_positions()

   Gibt eine iterierbare Struktur zurück, die die Positionen der
   einzelnen *bytecode*-Anweisungen im Code-Objekt enthält.

   Der Iterator gibt ein "tuple"s zurück, das die "(start_line,
   end_line, start_column, end_column)" enthält. Das *i-te* Tupel
   entspricht der Position im Quellcode, aus der die *i-te*
   Codeeinheit kompiliert wurde. Die Spaltenangaben sind 0-indizierte
   UTF-8-Byte-Offsets in der angegebenen Quellcodezeile.

   Diese Positionsangaben können fehlen. Hier eine nicht erschöpfende
   Liste von Fällen, in denen dies vorkommen kann:

   * Den Interpreter mit „ "-X" “ ausführen "no_debug_ranges".

   * Laden einer PYC-Datei, die mit "-X" "no_debug_ranges" kompiliert
     wurde.

   * Ordne die Tupel den künstlichen Befehlen zu.

   * Zeilen- und Spaltennummern, die aufgrund
     implementierungsspezifischer Einschränkungen nicht dargestellt
     werden können.

   In diesem Fall können einige oder alle Elemente des Tupels „ "None"
   “ sein.

   Added in version 3.11.

   Bemerkung:

     Diese Funktion erfordert die Speicherung von Spaltenpositionen in
     Code-Objekten, was zu einem geringfügigen Anstieg des
     Speicherplatzbedarfs kompilierter Python-Dateien oder des
     Speicherverbrauchs des Interpreter führen kann. Um die
     Speicherung dieser zusätzlichen Informationen zu vermeiden
     und/oder die Ausgabe der zusätzlichen Traceback-Informationen zu
     deaktivieren, können das Befehlszeilenflag „ "-X" “ (
     "no_debug_ranges" ) oder die Umgebungsvariable „
     "PYTHONNODEBUGRANGES" “ verwendet werden.

codeobject.co_lines()

   Gibt einen Iterator zurück, der Informationen über
   aufeinanderfolgende Bereiche von *bytecode* liefert. Jedes
   zurückgegebene Element ist ein "(start, end, lineno)" "tuple" :

   * "start" (ein "int") stellt den Offset (einschließlich) des
     Anfangs des *Bytecode*-Bereichs dar

   * "end" (ein "int") stellt den Offset (exklusiv) vom Ende des
     *Bytecode*-Bereichs dar

   * "lineno" ist ein "int", der die Zeilennummer des
     *bytecode*-Bereichs angibt, oder ein "None", wenn die Bytecodes
     im angegebenen Bereich keine Zeilennummer haben

   Die erzeugten Elemente weisen folgende Eigenschaften auf:

   * Der erste ermittelte Wertebereich weist einen „ "start" “ von 0
     auf.

   * Die Intervalle "(start, end)" sind nicht fallend und
     aufeinanderfolgend. Das heißt, für jedes Paar "tuple"s gilt: Die
     "start" des zweiten ist gleich der "end" des ersten.

   * Kein Bereich wird rückwärts verlaufen: "end >= start" für alle
     Tripel.

   * Der zuletzt zurückgegebene Wert von ` "tuple" ` hat einen Wert
     für ` "end" *, der der Größe des :term:`Bytecodes <bytecode>*
     entspricht.

   Bereiche mit der Breite Null, d.h. "start == end", sind zulässig.
   Bereiche mit der Breite Null werden für Zeilen verwendet, die im
   Quellcode vorhanden sind, aber vom *Bytecode*-Compiler entfernt
   wurden.

   Added in version 3.10.

   Siehe auch:

     **PEP 626** - Genaue Zeilennummern für die Fehlersuche und andere
     Tools.
        Der PEP, mit dem die Methode „ "co_lines()" “ eingeführt
        wurde.

codeobject.replace(**kwargs)

   Gibt eine Kopie des Code-Objekts mit neuen Werten für die
   angegebenen Felder zurück.

   Code-Objekte werden auch von der generischen Funktion „
   "copy.replace()" “ unterstützt.

   Added in version 3.8.


3.2.13.2. Rahmenobjekte
~~~~~~~~~~~~~~~~~~~~~~~

Frame-Objekte stellen Ausführungsframes dar. Sie können in Traceback-
Objekten vorkommen und werden zudem an registrierte Trace-Funktionen
übergeben.


3.2.13.2.1. Besondere schreibgeschützte Attribute
"""""""""""""""""""""""""""""""""""""""""""""""""

+----------------------------------------------------+----------------------------------------------------+
| frame.f_back                                       | Verweist auf den vorherigen Stack-Frame (in        |
|                                                    | Richtung des Aufrufers) oder auf "None", wenn dies |
|                                                    | der unterste Stack-Frame ist                       |
+----------------------------------------------------+----------------------------------------------------+
| frame.f_code                                       | Das code-Objekt, das in diesem Frame ausgeführt    |
|                                                    | wird. Der Zugriff auf dieses Attribut löst ein     |
|                                                    | Auditing-Ereignis "object.__getattr__" mit den     |
|                                                    | Argumenten "obj" und ""f_code"" aus.               |
+----------------------------------------------------+----------------------------------------------------+
| frame.f_locals                                     | Die Zuordnung, die der Frame zum Nachschlagen von  |
|                                                    | lokalen Variablen verwendet. Wenn sich der Frame   |
|                                                    | auf einen *optimierten Gültigkeitsbereich*         |
|                                                    | bezieht, kann dies ein Write-Through-Proxy-Objekt  |
|                                                    | zurückgeben.  Geändert in Version 3.13: Gibt einen |
|                                                    | Proxy für optimierte Bereiche zurück.              |
+----------------------------------------------------+----------------------------------------------------+
| frame.f_globals                                    | Das Wörterbuch, das vom Frame zum Nachschlagen von |
|                                                    | globalen Variablen                                 |
+----------------------------------------------------+----------------------------------------------------+
| frame.f_builtins                                   | Das vom Frame zum Nachschlagen verwendete          |
|                                                    | Wörterbuch: integrierte (intrinsische) Namen       |
+----------------------------------------------------+----------------------------------------------------+
| frame.f_lasti                                      | Die „genaue Anweisung“ des Frame-Objekts (dies ist |
|                                                    | ein Index in die *Bytecode*-Zeichenkette des Code- |
|                                                    | Objekts)                                           |
+----------------------------------------------------+----------------------------------------------------+


3.2.13.2.2. Besondere beschreibbare Attribute
"""""""""""""""""""""""""""""""""""""""""""""

+----------------------------------------------------+----------------------------------------------------+
| frame.f_trace                                      | Falls nicht "None", handelt es sich hierbei um     |
|                                                    | eine Funktion, die bei verschiedenen Ereignissen   |
|                                                    | während der Codeausführung aufgerufen wird (dies   |
|                                                    | wird von Debuggern genutzt). Normalerweise wird    |
|                                                    | für jede neue Quellcodezeile ein Ereignis          |
|                                                    | ausgelöst (siehe "f_trace_lines").                 |
+----------------------------------------------------+----------------------------------------------------+
| frame.f_trace_lines                                | Setze dieses Attribut auf „ "False" “, um die      |
|                                                    | Auslösung eines Trace- Ereignisses für jede        |
|                                                    | Quellcodezeile zu deaktivieren.                    |
+----------------------------------------------------+----------------------------------------------------+
| frame.f_trace_opcodes                              | Setze dieses Attribut auf „ "True" “, um die       |
|                                                    | Anforderung von Ereignissen pro Opcode zu          |
|                                                    | ermöglichen. Beachten Sie, dass dies zu einem      |
|                                                    | undefinierten Verhalten des Interpreters führen    |
|                                                    | kann, wenn von der Trace-Funktion ausgelöste       |
|                                                    | Ausnahmen in die zu verfolgende Funktion gelangen. |
+----------------------------------------------------+----------------------------------------------------+
| frame.f_lineno                                     | Die aktuelle Zeilennummer des Frames – wird hierin |
|                                                    | aus einer Trace- Funktion heraus geschrieben,      |
|                                                    | erfolgt ein Sprung zur angegebenen Zeile (gilt nur |
|                                                    | für den untersten Frame). Ein Debugger kann einen  |
|                                                    | Sprungbefehl (auch bekannt als „Nächste Anweisung  |
|                                                    | festlegen“) implementieren, indem er in dieses     |
|                                                    | Attribut schreibt.                                 |
+----------------------------------------------------+----------------------------------------------------+


3.2.13.2.3. Methoden von Frame-Objekten
"""""""""""""""""""""""""""""""""""""""

Frame-Objekte unterstützen eine Methode:

frame.clear()

   Diese Methode löscht alle Verweise auf lokale Variablen, die vom
   Frame gehalten werden.  Wenn der Frame zudem zu einem *Generator*
   gehörte, wird der Generator finalisiert. Dies hilft dabei,
   Referenzzyklen aufzubrechen, an denen Frame-Objekte beteiligt sind
   (beispielsweise beim Abfangen einer Ausnahme und dem Speichern
   ihres Tracebacks für die spätere Verwendung).

   "RuntimeError" wird ausgelöst, wenn der Frame gerade ausgeführt
   wird oder angehalten ist.

   Added in version 3.4.

   Geändert in Version 3.13: Der Versuch, einen angehaltenen Frame zu
   löschen, löst eine „ "RuntimeError" “-Ausnahme aus (wie dies bei
   der Ausführung von Frames schon immer der Fall war).


3.2.13.3. Traceback-Objekte
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Traceback-Objekte stellen den Stacktrace einer Ausnahme dar. Ein
Traceback-Objekt wird implizit erstellt, wenn eine Ausnahme auftritt,
und kann auch explizit durch den Aufruf von "types.TracebackType"
erstellt werden.

Geändert in Version 3.7: Traceback-Objekte können nun explizit aus
Python-Code instanziiert werden.

Bei implizit erstellten Tracebacks wird bei der Suche nach einem
Ausnahmebehandler der Ausführungsstapel abgewickelt, wobei auf jeder
abgewickelten Ebene ein Traceback-Objekt vor dem aktuellen Traceback
eingefügt wird. Wenn ein Ausnahmebehandler aufgerufen wird, wird der
Stack-Trace dem Programm zur Verfügung gestellt. (Siehe Abschnitt Die
try Anweisung.) Er ist als drittes Element des von "sys.exc_info()"
zurückgegebenen Tupels sowie als Attribut "__traceback__" der
abgefangenen Ausnahme zugänglich.

Wenn das Programm keinen geeigneten Handler enthält, wird der Stack-
Trace (übersichtlich formatiert) in den Standard-Fehlerstrom
geschrieben; ist der Interpreter interaktiv, wird er dem Benutzer
zudem unter "sys.last_traceback" zur Verfügung gestellt.

Bei explizit erstellten Tracebacks liegt es im Ermessen des
Erstellers, zu entscheiden, wie die Attribute „ "tb_next" “
miteinander verknüpft werden sollen, um einen vollständigen Stack-
Trace zu bilden.

Besondere schreibgeschützte Attribute:

+----------------------------------------------------+----------------------------------------------------+
| traceback.tb_frame                                 | Verweist auf den Ausführungs-Frame des aktuellen   |
|                                                    | Levels.  Der Zugriff auf dieses Attribut löst ein  |
|                                                    | Audit-Ereignis „ “ "object.__getattr__" mit den    |
|                                                    | Argumenten „ "obj" “ und „ ""tb_frame"" “ aus.     |
+----------------------------------------------------+----------------------------------------------------+
| traceback.tb_lineno                                | Gibt die Zeilennummer an, an der die Ausnahme      |
|                                                    | aufgetreten ist                                    |
+----------------------------------------------------+----------------------------------------------------+
| traceback.tb_lasti                                 | Bezeichnet die „genaue Anweisung“.                 |
+----------------------------------------------------+----------------------------------------------------+

Die Zeilennummer und die letzte Anweisung im Traceback können von der
Zeilennummer des zugehörigen Frame-Objekts abweichen, wenn die
Ausnahme in einer "try" -Anweisung ohne entsprechende except-Klausel
oder mit einer "finally" -Klausel aufgetreten ist.

traceback.tb_next

   Das spezielle beschreibbare Attribut „ "tb_next" “ bezeichnet die
   nächste Ebene im Stack-Trace (in Richtung des Frames, in dem die
   Ausnahme aufgetreten ist) oder „ "None" “, falls es keine nächste
   Ebene gibt.

   Geändert in Version 3.7: Dieses Attribut ist nun beschreibbar.


3.2.13.4. Objekte zerschneiden
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

„Slice“-Objekte dienen zur Darstellung von Schnitten für Methoden von
„ "__getitem__()" “. Sie werden außerdem durch die integrierte
Funktion „ "slice()" “ erstellt.

Spezielle schreibgeschützte Attribute: „ "start" “ ist die
Untergrenze; „ "stop" “ ist die Obergrenze; „ "step" “ ist der
Schrittwert; bei Auslassung gilt jeweils „ "None" “. Diese Attribute
können einen beliebigen Typ haben.

Slice-Objekte unterstützen eine Methode:

slice.indices(self, length)

   Diese Methode nimmt ein einzelnes ganzzahliges Argument *length*
   entgegen und berechnet Informationen über den Ausschnitt, den das
   Ausschnitt-Objekt beschreiben würde, wenn es auf eine Folge von
   *length* Elementen angewendet würde. Sie gibt ein Tupel aus drei
   Ganzzahlen zurück; dabei handelt es sich jeweils um die Indizes
   *start* und *stop* sowie um den *step* bzw. die Schrittweite des
   Ausschnitts. Fehlende oder außerhalb des zulässigen Bereichs
   liegende Indizes werden auf dieselbe Weise behandelt wie bei
   regulären Slices.


3.2.13.5. Statische Methodenobjekte
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Statische Methodenobjekte bieten eine Möglichkeit, die oben
beschriebene Umwandlung von Funktionsobjekten in Methodenobjekte zu
umgehen. Ein statisches Methodenobjekt ist eine Hülle um ein
beliebiges anderes Objekt, in der Regel ein benutzerdefiniertes
Methodenobjekt. Wird ein statisches Methodenobjekt aus einer Klasse
oder einer Klasseninstanz abgerufen, wird tatsächlich das umschlossene
Objekt zurückgegeben, das keiner weiteren Umwandlung unterliegt.
Statische Methodenobjekte sind zudem aufrufbar. Statische
Methodenobjekte werden mit dem integrierten Konstruktor `
"staticmethod()" ` erstellt.


3.2.13.6. Klassenmethodenobjekte
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Ein Klassenmethodenobjekt ist, ähnlich wie ein statisches
Methodenobjekt, eine Hülle um ein anderes Objekt, die die Art und
Weise verändert, wie dieses Objekt aus Klassen und Klasseninstanzen
abgerufen wird. Das Verhalten von Klassenmethodenobjekten bei einem
solchen Abruf wird oben unter „Instanzmethoden“ beschrieben.
Klassenmethodenobjekte werden mit dem integrierten Konstruktor
"classmethod()" erstellt.


3.3. Spezielle Methodennamen
============================

Eine Klasse kann bestimmte Operationen implementieren, die durch eine
spezielle Syntax aufgerufen werden (wie beispielsweise arithmetische
Operationen oder Indizierung und Slicing), indem sie Methoden mit
speziellen Namen definiert. Dies ist Pythons Ansatz für
*Operatorüberladung*, der es Klassen ermöglicht, ihr eigenes Verhalten
in Bezug auf Sprachoperatoren zu definieren.  Wenn eine Klasse
beispielsweise eine Methode namens "__getitem__()" definiert und "x"
eine Instanz dieser Klasse ist, dann entspricht "x[i]" in etwa
"type(x).__getitem__(x, i)". Sofern nicht anders angegeben, löst der
Versuch, eine Operation auszuführen, eine Ausnahme aus, wenn keine
entsprechende Methode definiert ist (typischerweise "AttributeError"
oder "TypeError").

Wird für eine bestimmte Methode der Wert „ "None" “ festgelegt,
bedeutet dies, dass die entsprechende Operation nicht verfügbar ist.
Wenn eine Klasse beispielsweise für „ "__iter__()" “ den Wert „ "None"
“ festlegt, ist die Klasse nicht iterierbar, sodass der Aufruf von „
"iter()" “ für ihre Instanzen eine Ausnahme vom Typ „ "TypeError" “
auslöst (ohne auf „ "__getitem__()" “ zurückzugreifen). [2]

Bei der Implementierung einer Klasse, die einen integrierten Typ
emuliert, ist es wichtig, dass die Emulation nur in dem Umfang
erfolgt, der für das modellierte Objekt sinnvoll ist. Beispielsweise
lassen sich bei manchen Sequenzen einzelne Elemente zwar gut abrufen,
doch das Extrahieren eines Ausschnitts ist möglicherweise nicht
sinnvoll. (Ein Beispiel hierfür ist die NodeList- -Schnittstelle im
Document Object Model des W3C.)


3.3.1. Grundlegende Anpassungen
-------------------------------

object.__new__(cls[, ...])

   Wird aufgerufen, um eine neue Instanz der Klasse *cls* zu erzeugen.
   "__new__()" ist eine statische Methode (als Sonderfall behandelt,
   du musst sie also nicht als solche deklarieren), die als erstes
   Argument die Klasse erhält, von der eine Instanz angefordert wurde.
   Die übrigen Argumente sind diejenigen, die dem Konstruktorausdruck
   des Objekts übergeben wurden – also dem Aufruf der Klasse. Der
   Rückgabewert von "__new__()" sollte die neue Objektinstanz sein,
   üblicherweise eine Instanz von *cls*.

   In typischen Implementierungen wird eine neue Instanz der Klasse
   erstellt, indem die Methode „ "__new__()" “ der Oberklasse mit „
   "super().__new__(cls[, ...])" “ und den entsprechenden Argumenten
   aufgerufen wird; anschließend wird die neu erstellte Instanz nach
   Bedarf angepasst, bevor sie zurückgegeben wird.

   Wird „ "__new__()" “ während der Objekterstellung aufgerufen und
   gibt eine Instanz von *cls* zurück, wird die Methode „ "__init__()"
   “ der neuen Instanz wie folgt aufgerufen: „ "__init__(self[, ...])"
   “, wobei *self* die neue Instanz ist und die übrigen Argumente mit
   denen übereinstimmen, die an den Objektkonstruktor übergeben
   wurden.

   Wenn „ "__new__()" “ keine Instanz von *cls* zurückgibt, wird die
   Methode „ "__init__()" “ der neuen Instanz nicht aufgerufen.

   "__new__()" Dient in erster Linie dazu, Unterklassen
   unveränderlicher Typen (wie int, str oder tuple) die Möglichkeit zu
   geben, die Instanzerstellung anzupassen. Außerdem wird sie häufig
   in benutzerdefinierten Metaklassen überschrieben, um die
   Klassenerstellung anzupassen.

object.__init__(self[, ...])

   Wird aufgerufen, nachdem die Instanz erstellt wurde (durch
   "__new__()"), jedoch bevor sie an den Aufrufer zurückgegeben wird.
   Die Argumente entsprechen denen, die an den Konstruktorausdruck der
   Klasse übergeben wurden. Verfügt eine Basisklasse über eine
   "__init__()"-Methode, muss die "__init__()"-Methode der
   abgeleiteten Klasse – sofern vorhanden – diese explizit aufrufen,
   um die korrekte Initialisierung des Basisklassen-Teils der Instanz
   sicherzustellen; zum Beispiel: "super().__init__([args...])".

   Da „ "__new__()" “ und „ "__init__()" “ bei der Erstellung von
   Objekten zusammenwirken (mit „"__new__()" “ zur Erstellung und „
   "__init__()" “ zur Anpassung), darf „ "__init__()" “ keinen Wert
   zurückgeben, der nicht „"None" “ ist; andernfalls wird zur Laufzeit
   eine „ "TypeError" “ ausgelöst.

object.__del__(self)

   Wird aufgerufen, wenn die Instanz kurz vor der Löschung steht. Dies
   wird auch als Finalizer oder (fälschlicherweise) als Destruktor
   bezeichnet. Verfügt eine Basisklasse über eine "__del__()"-Methode,
   muss die "__del__()"-Methode der abgeleiteten Klasse – sofern
   vorhanden – diese explizit aufrufen, um die ordnungsgemäße Löschung
   des Teils der Instanz zu gewährleisten, der zur Basisklasse gehört.

   Es ist möglich (wenn auch nicht empfehlenswert!), dass die Methode
   „ "__del__()" “ die Zerstörung der Instanz aufschiebt, indem sie
   eine neue Referenz auf diese erstellt.  Dies wird als
   *Wiederbelebung* des Objekts bezeichnet. Es ist
   implementierungsabhängig, ob ` "__del__()" ` ein zweites Mal
   aufgerufen wird, wenn ein wiederbelebtes Objekt kurz vor der
   Zerstörung steht; die aktuelle *CPython*-Implementierung ruft die
   Funktion nur einmal auf.

   Es ist nicht gewährleistet, dass die Methoden „ "__del__()" “ für
   Objekte aufgerufen werden, die beim Beenden des Interpreters noch
   vorhanden sind. „ "weakref.finalize" “ bietet eine einfache
   Möglichkeit, eine Aufräumfunktion zu registrieren, die aufgerufen
   wird, wenn ein Objekt von der Garbage Collection entfernt wird.

   Bemerkung:

     "del x" ruft „ "x.__del__()" “ nicht direkt auf – Ersteres
     verringert die Referenzanzahl für „ "x" “ um eins, und Letzteres
     wird erst aufgerufen, wenn die Referenzanzahl von „ "x" “ den
     Wert Null erreicht.

   Ein Referenzzyklus kann verhindern, dass die Referenzanzahl eines
   Objekts auf Null sinkt.  In diesem Fall wird der Zyklus später vom
   *zyklischen Garbage Collector* erkannt und gelöscht. Eine häufige
   Ursache für Referenzzyklen ist, wenn eine Ausnahme in einer lokalen
   Variablen abgefangen wurde. Die lokalen Variablen des Frames
   verweisen dann auf die Ausnahme, die wiederum auf ihren eigenen
   Traceback verweist, der wiederum auf die lokalen Variablen aller im
   Traceback erfassten Frames verweist.

   Siehe auch: Dokumentation zum Modul „ "gc" “.

   Warnung:

     Aufgrund der heiklen Umstände, unter denen die Methoden von „
     "__del__()" “ aufgerufen werden, werden Ausnahmen, die während
     ihrer Ausführung auftreten, ignoriert, und stattdessen wird eine
     Warnung an „ "sys.stderr" “ ausgegeben. Insbesondere gilt
     Folgendes:

     * "__del__()" kann aufgerufen werden, wenn beliebiger Code
       ausgeführt wird, auch aus einem beliebigen Thread. Wenn „
       "__del__()" “ eine Sperre erwerben oder eine andere
       blockierende Ressource aufrufen muss, kann es zu einem Deadlock
       kommen, da die Ressource möglicherweise bereits von dem Code
       belegt ist, der unterbrochen wird, um „ "__del__()" “
       auszuführen.

     * "__del__()" kann während des Beendens des Interpreters
       ausgeführt werden. Infolgedessen können die globalen Variablen,
       auf die es zugreifen muss (einschließlich anderer Module),
       möglicherweise bereits gelöscht oder auf „ "None" “ gesetzt
       worden sein. Python garantiert, dass globale Variablen, deren
       Name mit einem einzelnen Unterstrich beginnt, vor der Löschung
       anderer globaler Variablen aus ihrem Modul entfernt werden;
       wenn keine weiteren Verweise auf solche globalen Variablen
       bestehen, kann dies dazu beitragen, sicherzustellen, dass
       importierte Module zum Zeitpunkt des Aufrufs der Methode `
       "__del__()" ` noch verfügbar sind.

object.__repr__(self)

   Wird von der integrierten Funktion ` "repr()" ` aufgerufen, um die
   „offizielle“ Zeichenfolgendarstellung eines Objekts zu berechnen.
   Wenn möglich, sollte diese wie ein gültiger Python-Ausdruck
   aussehen, mit dem ein Objekt mit demselben Wert (unter geeigneten
   Umgebungsbedingungen) neu erstellt werden könnte. Ist dies nicht
   möglich, sollte eine Zeichenfolge der Form "<...some useful
   description...>" zurückgegeben werden. Der Rückgabewert muss ein
   String-Objekt sein. Wenn eine Klasse "__repr__()" definiert, aber
   nicht "__str__()", wird "__repr__()" ebenfalls verwendet, wenn eine
   „informelle“ String-Darstellung von Instanzen dieser Klasse
   erforderlich ist.

   Dies wird in der Regel zur Fehlersuche verwendet, daher ist es
   wichtig, dass die Darstellung aussagekräftig und eindeutig ist.
   Eine Standardimplementierung wird von der Klasse „ "object" “
   selbst bereitgestellt.

object.__str__(self)

   Aufgerufen von "str(object)", der Standard "__format__()"
   -Implementierung und der integrierten Funktion "print()", um die
   „informelle“ oder gut darstellbare Zeichenfolgendarstellung eines
   Objekts zu berechnen. Der Rückgabewert muss ein str -Objekt sein.

   Diese Methode unterscheidet sich von „ "object.__repr__()" “
   dadurch, dass nicht erwartet wird, dass „ "__str__()" “ einen
   gültigen Python-Ausdruck zurückgibt: Es kann eine bequemere oder
   prägnantere Darstellung verwendet werden.

   Die durch den integrierten Typ „ "object" “ definierte
   Standardimplementierung ruft „ "object.__repr__()" “ auf.

object.__bytes__(self)

   Wird von bytes aufgerufen, um eine Byte-String-Darstellung eines
   Objekts zu berechnen. Diese Methode sollte ein "bytes" -Objekt
   zurückgeben. Die Klasse "object" selbst stellt diese Methode nicht
   bereit.

object.__format__(self, format_spec)

   Wird von der integrierten Funktion "format()" sowie – im weiteren
   Sinne – bei der Auswertung von formatierten String-Literalen und
   der Methode "str.format()" aufgerufen, um eine „formatierte“
   String-Darstellung eines Objekts zu erzeugen. Das Argument
   *format_spec* ist ein String, der eine Beschreibung der gewünschten
   Formatierungsoptionen enthält. Die Interpretation des Arguments
   *format_spec* liegt im Ermessen des Typs, der "__format__()"
   implementiert. Die meisten Klassen delegieren die Formatierung
   jedoch entweder an einen der integrierten Typen oder verwenden eine
   ähnliche Syntax für Formatierungsoptionen.

   Eine Beschreibung der Standard-Formatierungssyntax findest du unter
   Formatspezifikation Mini-Sprache.

   Der Rückgabewert muss ein String-Objekt sein.

   Der Standardimplementierung durch die Klasse „ "object" “ sollte
   eine leere *format_spec*-Zeichenkette übergeben werden. Sie
   delegiert an „ "__str__()" “.

   Geändert in Version 3.4: Die Methode __format__ von ` "object" `
   löst selbst eine ` "TypeError" ` aus, wenn ihr eine nicht leere
   Zeichenkette übergeben wird.

   Geändert in Version 3.7: "object.__format__(x, '')" entspricht nun
   „ "str(x)" “ statt „ "format(str(x), '')" “.

object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)

   Dies sind die sogenannten „Rich-Comparison“-Methoden. Die Zuordnung
   zwischen den Operatorsymbolen und den Methodennamen lautet wie
   folgt: „ "x<y" “ ruft „ "x.__lt__(y)" “ auf, „ "x<=y" “ ruft „
   "x.__le__(y)" “ auf, „ "x==y" “ ruft „ "x.__eq__(y)" “ auf, „
   "x!=y" “ ruft „ "x.__ne__(y)" “ auf, „ "x>y" “ ruft „ "x.__gt__(y)"
   “ auf und „ "x>=y" “ ruft „ "x.__ge__(y)" “ auf.

   Eine erweiterte Vergleichsmethode darf das Singleton
   "NotImplemented" zurückgeben, wenn sie die Operation für ein
   bestimmtes Argumentpaar nicht umsetzt. Üblicherweise werden "False"
   und "True" für einen erfolgreichen Vergleich zurückgegeben. Diese
   Methoden können jedoch jeden beliebigen Wert zurückgeben; wird der
   Vergleichsoperator also in einem booleschen Kontext verwendet –
   etwa in der Bedingung einer "if"-Anweisung –, ruft Python "bool()"
   für den Wert auf, um zu bestimmen, ob das Ergebnis wahr oder falsch
   ist.

   Standardmäßig implementiert „ "object" “ die Funktion „ "__eq__()"
   “ mithilfe von „ "is" “ und gibt im Falle eines falschen Vergleichs
   „ "NotImplemented" “ zurück: „ "True if x is y else NotImplemented"
   “. Bei „ "__ne__()" “ wird standardmäßig an „ "__eq__()" “
   delegiert und das Ergebnis umgekehrt, es sei denn, es handelt sich
   um „ "NotImplemented" “. Es gibt keine weiteren impliziten
   Beziehungen zwischen den Vergleichsoperatoren oder
   Standardimplementierungen; so impliziert beispielsweise die
   Wahrheit von „ "(x<y or x==y)" “ nicht, dass „ "x<=y" “ gilt.
   Informationen zur automatischen Generierung von Ordnungsoperationen
   aus einer einzigen Stammoperation findest du unter „
   "@functools.total_ordering" “.

   Standardmäßig bietet die Klasse „ "object" “ Implementierungen, die
   mit Wertvergleiche übereinstimmen: Der Gleichheitsvergleich erfolgt
   anhand der Objektidentität, und beim Vergleich der Reihenfolge wird
   „ "TypeError" “ ausgelöst. Jede Standardmethode kann diese
   Ergebnisse direkt generieren, kann aber auch „ "NotImplemented" “
   zurückgeben.

   Im Abschnitt über „ "__hash__()" “ findest du einige wichtige
   Hinweise zur Erstellung von *hashable*-Objekten, die
   benutzerdefinierte Vergleichsoperationen unterstützen und als
   Schlüssel in Wörterbüchern verwendet werden können.

   Es gibt keine Versionen dieser Methoden mit vertauschten Argumenten
   (die verwendet werden, wenn das linke Argument die Operation nicht
   unterstützt, das rechte Argument jedoch schon); vielmehr sind
   "__lt__()" und "__gt__()" die jeweiligen Spiegelbilder zueinander,
   "__le__()" und "__ge__()" sind die jeweiligen Spiegelbilder
   zueinander, und "__eq__()" und "__ne__()" sind ihre eigenen
   Spiegelbilder. Sind die Operanden unterschiedlicher Typen und ist
   der Typ des rechten Operanden eine direkte oder indirekte
   Unterklasse des Typs des linken Operanden, hat die reflektierte
   Methode des rechten Operanden Vorrang; andernfalls hat die Methode
   des linken Operanden Vorrang. Virtuelle Unterklassen werden nicht
   berücksichtigt.

   Wenn keine geeignete Methode einen anderen Wert als „
   "NotImplemented" “ zurückgibt, greifen die Operatoren „ "==" “ und
   „ "!=" “ jeweils auf „ "is" “ bzw. „ "is not" “ zurück.

object.__hash__(self)

   Wird von der integrierten Funktion „ "hash()" “ sowie für
   Operationen auf Elementen von Hash-Sammlungen aufgerufen, darunter
   „ "set" “, „ "frozenset" “ und „ "dict" “. Die Methode „
   "__hash__()" “ sollte eine Ganzzahl zurückgeben. Die einzige
   erforderliche Eigenschaft ist, dass Objekte, die als gleich
   verglichen werden, denselben Hash-Wert haben; es wird empfohlen,
   die Hash-Werte der Komponenten des Objekts, die ebenfalls eine
   Rolle beim Vergleich von Objekten spielen, zusammenzufassen, indem
   man sie in ein Tupel packt und das Tupel hasht. Beispiel:

      def __hash__(self):
          return hash((self.name, self.nick, self.color))

   Bemerkung:

     "hash()" kürzt den von der benutzerdefinierten Methode
     "__hash__()" eines Objekts zurückgegebenen Wert auf die Größe
     eines "Py_ssize_t". Dies sind in der Regel 8 Byte bei 64-Bit-
     Builds und 4 Byte bei 32-Bit-Builds. Wenn die Methode
     "__hash__()" eines Objekts auf Builds mit unterschiedlichen
     Bitgrößen kompatibel sein muss, solltest du die Breite auf allen
     unterstützten Builds überprüfen. Eine einfache Möglichkeit
     hierfür ist die Verwendung von "python -c "import sys;
     print(sys.hash_info.width)"".

   Definiert eine Klasse keine Methode "__eq__()", sollte sie auch
   keine Operation "__hash__()" definieren; definiert sie "__eq__()",
   aber nicht "__hash__()", lassen sich ihre Instanzen nicht als
   Elemente in hashbaren Sammlungen verwenden. Definiert eine Klasse
   veränderbare Objekte und implementiert eine Methode "__eq__()",
   sollte sie "__hash__()" nicht implementieren, denn die Umsetzung
   *hashbarer* Sammlungen setzt voraus, dass der Hashwert eines
   Schlüssels unveränderlich ist – ändert sich der Hashwert eines
   Objekts, landet es im falschen Hash-Bucket.

   Benutzerdefinierte Klassen verfügen standardmäßig über die Methoden
   „ "__eq__()" “ und „ "__hash__()" “ (geerbt von der Klasse „
   "object" “); mit diesen Methoden sind alle Objekte ungleich (außer
   mit sich selbst), und „ "x.__hash__()" “ gibt einen geeigneten Wert
   zurück, sodass „ "x == y" “ sowohl „ "x is y" “ als auch „ "hash(x)
   == hash(y)" “ impliziert.

   Bei einer Klasse, die ` "__eq__()" ` überschreibt und `
   "__hash__()" ` nicht definiert, wird ` "__hash__()" ` implizit auf
   ` "None`" gesetzt. Wenn die Methode ` "__hash__()" ` einer Klasse `
   "None`" lautet, lösen Instanzen dieser Klasse eine entsprechende `
   "TypeError" ` aus, sobald ein Programm versucht, ihren Hash-Wert
   abzurufen, und werden bei der Überprüfung von ` "isinstance(obj,
   collections.abc.Hashable)`" korrekt als „unhashable“ identifiziert.

   Wenn eine Klasse, die ` "__eq__()" ` überschreibt, die
   Implementierung von ` "__hash__()" ` aus einer übergeordneten
   Klasse beibehalten soll, muss dies dem Interpreter explizit
   mitgeteilt werden, indem ` "__hash__ = <ParentClass>.__hash__`"
   gesetzt wird.

   Wenn eine Klasse, die ` "__eq__()" ` nicht überschreibt, die Hash-
   Unterstützung unterdrücken möchte, sollte sie ` "__hash__ = None" `
   in die Klassendefinition aufnehmen. Eine Klasse, die eine eigene
   Methode ` "__hash__()" ` definiert, die explizit eine ` "TypeError"
   ` auslöst, würde durch einen Aufruf von ` "isinstance(obj,
   collections.abc.Hashable)" ` fälschlicherweise als „hashable“
   identifiziert werden.

   Bemerkung:

     Standardmäßig werden die Werte „ "__hash__()" “ von *str*- und
     *bytes*-Objekten mit einem unvorhersehbaren Zufallswert
     „gesalzen“. Obwohl sie innerhalb eines einzelnen Python-Prozesses
     konstant bleiben, sind sie bei wiederholten Aufrufen von Python
     nicht vorhersehbar.Dies soll Schutz vor einem Denial-of-Service-
     Angriff bieten, der durch sorgfältig ausgewählte Eingaben
     verursacht wird, die die Leistung im ungünstigsten Fall beim
     Einfügen in ein Wörterbuch ausnutzen, nämlich eine Komplexität
     von *O*(*n*^2). Weitere Informationen findest du unter
     https://ocert.org/advisories/ocert-2011-003.html.Das Ändern von
     Hash-Werten wirkt sich auf die Iterationsreihenfolge von Mengen
     aus. Python hat hinsichtlich dieser Reihenfolge niemals Garantien
     gegeben (und sie variiert in der Regel zwischen 32-Bit- und 64
     -Bit-Builds).Siehe auch "PYTHONHASHSEED".

   Geändert in Version 3.3: Die Hash-Randomisierung ist standardmäßig
   aktiviert.

object.__bool__(self)

   Wird aufgerufen, um die Überprüfung des Wahrheitswerts und die
   integrierte Operation „ "bool()" “ zu implementieren; sollte „
   "False" “ oder „ "True" “ zurückgeben. Ist diese Methode nicht
   definiert, wird „ "__len__()" “ aufgerufen, sofern diese definiert
   ist, und das Objekt gilt als wahr, wenn das Ergebnis ungleich Null
   ist. Definiert eine Klasse weder „ "__len__()" “ noch „
   "__bool__()" “ (was auf die Klasse „ "object" “ selbst zutrifft),
   gelten alle ihre Instanzen als wahr.


3.3.2. Anpassung des Zugriffs auf Attribute
-------------------------------------------

Die folgenden Methoden können definiert werden, um die Bedeutung des
Attributzugriffs (Verwendung, Zuweisung oder Löschung von "x.name")
für Klasseninstanzen anzupassen.

object.__getattr__(self, name)

   Wird aufgerufen, wenn der Zugriff auf das Standardattribut mit
   einer „ "AttributeError" “-Ausnahme fehlschlägt (entweder löst „
   "__getattribute__()" “ eine „ "AttributeError" “-Ausnahme aus, weil
   *name* kein Instanzattribut oder kein Attribut im Klassenbaum für „
   "self" “ ist; oder löst „ "__get__()" “ einer *name*-Eigenschaft
   eine „ "AttributeError" “-Ausnahme aus). Diese Methode sollte
   entweder den (berechneten) Attributwert zurückgeben oder eine „
   "AttributeError" “-Ausnahme auslösen. Die Klasse „ "object" “
   selbst stellt diese Methode nicht bereit.

   Beachte, dass "__getattr__()" nicht aufgerufen wird, wenn das
   Attribut über den normalen Mechanismus gefunden wird. (Das ist eine
   bewusste Asymmetrie zwischen "__getattr__()" und "__setattr__()".)
   Der Grund ist zum einen die Effizienz, zum anderen hätte
   "__getattr__()" sonst keine Möglichkeit, auf andere Attribute der
   Instanz zuzugreifen. Beachte außerdem, dass du zumindest bei
   Instanzvariablen die vollständige Kontrolle übernehmen kannst,
   indem du gar keine Werte in das Attribut-Dictionary der Instanz
   einträgst, sondern in ein anderes Objekt. Wie du tatsächlich die
   vollständige Kontrolle über den Attributzugriff erhältst, zeigt die
   Methode "__getattribute__()" weiter unten.

object.__getattribute__(self, name)

   Wird bedingungslos aufgerufen, um Attributzugriffe für Instanzen
   der Klasse zu implementieren. Wenn die Klasse auch "__getattr__()"
   definiert, wird letztere nur dann aufgerufen, wenn
   "__getattribute__()" sie entweder explizit aufruft oder eine
   "AttributeError" auslöst. Diese Methode sollte den (berechneten)
   Attributwert zurückgeben oder eine "AttributeError"-Ausnahme
   auslösen. Um eine unendliche Rekursion in dieser Methode zu
   vermeiden, sollte ihre Implementierung stets die gleichnamige
   Methode der Basisklasse aufrufen, um auf benötigte Attribute
   zuzugreifen, zum Beispiel "object.__getattribute__(self, name)".

   Bemerkung:

     Diese Methode kann dennoch umgangen werden, wenn spezielle
     Methoden als Ergebnis eines impliziten Aufrufs über die
     Sprachsyntax oder integrierte Funktionen aufgerufen werden. Siehe
     Suche nach speziellen Methoden.

   Bei bestimmten Zugriffen auf sensible Attribute wird ein Audit-
   Ereignis „ “ "object.__getattr__" mit den Argumenten "obj" und
   "name" ausgelöst.

object.__setattr__(self, name, value)

   Wird aufgerufen, wenn versucht wird, ein Attribut zuzuweisen. Diese
   Funktion wird anstelle des üblichen Mechanismus aufgerufen (d.h.
   Speichern des Werts im Instanz-Wörterbuch). *name* ist der Name des
   Attributs, *value* ist der Wert, der ihm zugewiesen werden soll.

   Wenn „ "__setattr__()" “ einem Instanzattribut einen Wert zuweisen
   möchte, sollte es die gleichnamige Methode der Basisklasse
   aufrufen, zum Beispiel „ "object.__setattr__(self, name, value)" “.

   Bei bestimmten Zuweisungen sensibler Attribute wird ein Audit-
   Ereignis "object.__setattr__" mit den Argumenten "obj", "name" und
   "value" ausgelöst.

object.__delattr__(self, name)

   Ähnlich wie „ "__setattr__()" “, jedoch zum Löschen statt zum
   Zuweisen von Attributen. Dies sollte nur implementiert werden, wenn
   „ "del obj.name" “ für das Objekt sinnvoll ist.

   Bei bestimmten Löschvorgängen sensibler Attribute wird ein Audit-
   Ereignis „ “ "object.__delattr__" mit den Argumenten „ "obj" “ und
   „ "name" “ ausgelöst.

object.__dir__(self)

   Wird aufgerufen, wenn für das Objekt die Methode „ "dir()" “
   aufgerufen wird. Es muss ein iterierbares Objekt zurückgegeben
   werden. „ "dir()" “ wandelt das zurückgegebene iterierbare Objekt
   in eine Liste um und sortiert diese.


3.3.2.1. Anpassung des Zugriffs auf Modulattribute
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

module.__getattr__()
module.__dir__()

Die Spezialnamen "__getattr__" und "__dir__" lassen sich auch nutzen,
um den Zugriff auf Modulattribute anzupassen. Die Funktion
"__getattr__" auf Modulebene sollte ein Argument entgegennehmen – den
Namen eines Attributs – und den berechneten Wert zurückgeben oder
einen "AttributeError" auslösen. Wird ein Attribut über die normale
Suche, also "object.__getattribute__()", nicht in einem Modulobjekt
gefunden, wird "__getattr__" im "__dict__" des Moduls gesucht, bevor
ein "AttributeError" ausgelöst wird. Wird es gefunden, wird es mit dem
Attributnamen aufgerufen und das Ergebnis zurückgegeben.

Die Funktion "__dir__" sollte keine Argumente entgegennehmen und eine
iterierbare Struktur aus Zeichenfolgen zurückgeben, die die im Modul
verfügbaren Namen darstellt. Sofern vorhanden, überschreibt diese
Funktion die Standard-Suche nach Modulen über "dir()".

module.__class__

Für eine detailliertere Anpassung des Modulverhaltens (Festlegen von
Attributen, Eigenschaften usw.) kann man das Attribut „ "__class__" “
eines Modulobjekts auf eine Unterklasse von „ "types.ModuleType" “
setzen. Zum Beispiel:

   import sys
   from types import ModuleType

   class VerboseModule(ModuleType):
       def __repr__(self):
           return f'Verbose {self.__name__}'

       def __setattr__(self, attr, value):
           print(f'{attr} wird gesetzt...')
           super().__setattr__(attr, value)

   sys.modules[__name__].__class__ = VerboseModule

Bemerkung:

  Die Definition von ` "__getattr__" ` und die Festlegung von `
  "__class__" ` wirken sich nur auf Abfragen aus, die über die
  Attributzugriffssyntax erfolgen – der direkte Zugriff auf die
  globalen Variablen des Moduls (sei es durch Code innerhalb des
  Moduls oder über einen Verweis auf das globale Wörterbuch des
  Moduls) bleibt davon unberührt.

Geändert in Version 3.5: "__class__" Das Modul-Attribut ist nun
beschreibbar.

Added in version 3.7: "__getattr__" sowie die Modulattribute „
"__dir__" “.

Siehe auch:

  **PEP 562** - Die Module __getattr__ und __dir__
     Beschreibt die Funktionen „ "__getattr__" “ und „ "__dir__" “ für
     Module.


3.3.2.2. Implementierung von Deskriptoren
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Die folgenden Methoden gelten nur, wenn eine Instanz der Klasse, die
die Methode enthält (eine sogenannte *Deskriptor*-Klasse), in einer
*Eigentümer*-Klasse vorkommt (der Deskriptor muss sich entweder im
Klassendictionary des Eigentümers oder im Klassendictionary einer
seiner übergeordneten Klassen befinden).  In den folgenden Beispielen
bezieht sich „das Attribut“ auf das Attribut, dessen Name der
Schlüssel der Eigenschaft im * " Die Klasse * :class:`object" * selbst
implementiert keines dieser Protokolle.

object.__get__(self, instance, owner=None)

   Wird aufgerufen, um das Attribut der Eigentümerklasse (Zugriff auf
   Klassenattribute) oder einer Instanz dieser Klasse (Zugriff auf
   Instanzattribute) abzurufen. Das optionale Argument *owner* ist die
   Eigentümerklasse, während *instance* die Instanz ist, über die auf
   das Attribut zugegriffen wurde, oder "None", wenn über *owner* auf
   das Attribut zugegriffen wird.

   Diese Methode sollte den berechneten Attributwert zurückgeben oder
   eine Ausnahme vom Typ „ "AttributeError" “ auslösen.

   **PEP 252** legt fest, dass ` "__get__()" ` mit einem oder zwei
   Argumenten aufgerufen werden kann. Die in Python integrierten
   Deskriptoren unterstützen diese Spezifikation; es ist jedoch
   wahrscheinlich, dass einige Tools von Drittanbietern Deskriptoren
   verwenden, die beide Argumente erfordern. Die Python-eigene
   Implementierung von ` "__getattribute__()" ` übergibt immer beide
   Argumente, unabhängig davon, ob sie erforderlich sind oder nicht.

object.__set__(self, instance, value)

   Wird aufgerufen, um das Attribut einer Instanz *instance* der
   Eigentümerklasse auf einen neuen Wert, *value*, zu setzen.

   Beachten Sie: Durch Hinzufügen von „ "__set__()" “ oder „
   "__delete__()" “ wird der Deskriptortyp in einen „Datendeskriptor“
   geändert. Weitere Informationen findest du unter Deskriptoren
   aufrufen.

object.__delete__(self, instance)

   Wird aufgerufen, um das Attribut einer Instanz *instance* der
   Eigentümerklasse zu löschen.

Instanzen von Deskriptoren können auch das Attribut „ "__objclass__" “
aufweisen:

object.__objclass__

   Das Attribut „ "__objclass__" “ wird vom Modul „ "inspect" “ als
   Angabe der Klasse interpretiert, in der dieses Objekt definiert
   wurde (eine entsprechende Einstellung kann bei der Laufzeit-
   Introspektion dynamischer Klassenattribute hilfreich sein). Bei
   aufrufbaren Objekten kann es darauf hinweisen, dass eine Instanz
   des angegebenen Typs (oder einer Unterklasse) als erstes
   Positionsargument erwartet oder erforderlich ist (CPython setzt
   dieses Attribut beispielsweise für ungebundene Methoden, die in C
   implementiert sind).


3.3.2.3. Deskriptoren aufrufen
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Im Allgemeinen ist ein Deskriptor ein Objektattribut mit
„Bindungsverhalten“, d.h. ein Attribut, dessen Zugriff durch Methoden
des Deskriptorprotokolls überschrieben wurde: "__get__()" ,
"__set__()" und "__delete__()". Ist eine dieser Methoden für ein
Objekt definiert, wird dieses als Deskriptor bezeichnet.

Das Standardverhalten beim Zugriff auf Attribute besteht darin, das
Attribut aus dem Wörterbuch eines Objekts abzurufen, festzulegen oder
zu löschen. Beispielsweise verfügt „ "a.x" “ über eine Suchkette, die
mit „ "a.__dict__['x']" “ beginnt, dann über „ "type(a).__dict__['x']"
“ verläuft und sich über die Basisklassen von „ "type(a)" “ fortsetzt,
wobei Metaklassen ausgeschlossen sind.

Ist der nachgeschlagene Wert jedoch ein Objekt, das eine der
Deskriptormethoden definiert, kann Python das Standardverhalten außer
Kraft setzen und stattdessen die Deskriptormethode aufrufen. An
welcher Stelle in der Prioritätskette dies geschieht, hängt davon ab,
welche Deskriptormethoden definiert wurden und wie sie aufgerufen
wurden.

Ausgangspunkt für den Aufruf eines Deskriptors ist eine Bindung,
"a.x". Wie die Argumente zusammengestellt werden, hängt von "a" ab:

Direktanruf
   Der einfachste und seltenste Aufruf ist der Fall, bei dem der
   Benutzercode eine Deskriptormethode direkt aufruft:
   "x.__get__(a)" .

Instanzbindung
   Bei der Bindung an eine Objektinstanz wird „ "a.x" “ in den Aufruf
   „ "type(a).__dict__['x'].__get__(a, type(a))" “ umgewandelt.

Klassenbindung
   Bei der Bindung an eine Klasse wird „ "A.x" “ in den Aufruf „
   "A.__dict__['x'].__get__(None, A)" “ umgewandelt.

Super-Bindung
   Bei einer gepunkteten Suche wie beispielsweise „ "super(A, a).x" “
   wird auf „ "a.__class__.__mro__" “ nach einer Basisklasse „ "B" “
   gesucht, die auf „ "A" “ folgt, und anschließend wird „
   "B.__dict__['x'].__get__(a, A)" “ zurückgegeben. Handelt es sich
   nicht um einen Deskriptor, wird „ "x" “ unverändert zurückgegeben.

Bei Instanzbindungen hängt der Vorrang beim Aufruf eines Deskriptors
davon ab, welche Deskriptormethoden definiert sind. Ein Deskriptor
kann jede Kombination aus "__get__()", "__set__()" und "__delete__()"
definieren. Definiert er "__get__()" nicht, gibt der Zugriff auf das
Attribut das Deskriptorobjekt selbst zurück, sofern im Instanz-
Dictionary des Objekts kein Wert steht. Definiert der Deskriptor
"__set__()" und/oder "__delete__()", ist er ein Daten-Deskriptor;
definiert er keines von beiden, ist er ein Nicht-Daten-Deskriptor.
Üblicherweise definieren Daten-Deskriptoren sowohl "__get__()" als
auch "__set__()", während Nicht-Daten-Deskriptoren nur die Methode
"__get__()" haben. Daten-Deskriptoren mit definiertem "__get__()" und
"__set__()" (und/oder "__delete__()") haben immer Vorrang vor einer
Neudefinition in einem Instanz-Dictionary. Nicht-Daten-Deskriptoren
können dagegen von Instanzen überschrieben werden.

Python-Methoden (einschließlich derjenigen, die mit „ "@staticmethod"
“ und „ "@classmethod" “ dekoriert sind) werden als Nicht-Daten-
Deskriptoren implementiert. Dementsprechend können Instanzen Methoden
neu definieren und überschreiben. Dadurch können einzelne Instanzen
Verhaltensweisen annehmen, die sich von denen anderer Instanzen
derselben Klasse unterscheiden.

Der Dekorator „ "@property" “ ist als Datenbeschreiber implementiert.
Daher können Instanzen das Verhalten einer Eigenschaft nicht
überschreiben.


3.3.2.4. __slots__
~~~~~~~~~~~~~~~~~~

Mit *__slots__* können wir Datenelemente (wie Eigenschaften) explizit
deklarieren und die Erstellung von "__dict__" und *__weakref__*
verhindern (es sei denn, sie wurden explizit in *__slots__* deklariert
oder sind in einer übergeordneten Klasse verfügbar).

Die Platzersparnis gegenüber der Verwendung von „ "__dict__" “ kann
beträchtlich sein. Auch die Geschwindigkeit der Attributsuche lässt
sich deutlich verbessern.

object.__slots__

   Dieser Klassenvariablen kann eine Zeichenkette, ein iterierbares
   Objekt oder eine Folge von Zeichenketten mit den von Instanzen
   verwendeten Variablennamen zugewiesen werden. *__slots__*
   reserviert Platz für die deklarierten Variablen und verhindert die
   automatische Erstellung von "__dict__" und *__weakref__* für jede
   Instanz.

Hinweise zur Verwendung von *__slots__*:

* Bei der Vererbung von einer Klasse ohne *__slots__* sind die
  Attribute "__dict__" und *__weakref__* der Instanzen immer
  zugänglich.

* Ohne die Variable "__dict__" können Instanzen keine neuen Variablen
  zugewiesen werden, die nicht in der Definition von *__slots__*
  aufgeführt sind. Der Versuch, eine nicht aufgeführte Variable
  zuzuweisen, löst einen "AttributeError" aus. Wenn eine dynamische
  Zuweisung neuer Variablen gewünscht ist, fügst du "'__dict__'" zur
  Zeichenfolgenfolge in der *__slots__*-Deklaration hinzu.

* Ohne eine *__weakref__*-Variable für jede Instanz unterstützen
  Klassen, die *__slots__* definieren, keine "schwachen Referenzen"
  auf ihre Instanzen. Wenn die Unterstützung für schwache Referenzen
  benötigt wird, fügest du "'__weakref__'" zur Zeichenfolgenfolge in
  der *__slots__*-Deklaration hinzu.

* *__slots__* werden auf Klassenebene implementiert, indem für jeden
  Variablennamen Deskriptoren erstellt werden. Daher können
  Klassenattribute nicht verwendet werden, um Standardwerte für
  Instanzvariablen festzulegen, die durch *__slots__* definiert sind;
  andernfalls würde das Klassenattribut die Zuweisung des Deskriptors
  überschreiben.

* Die Wirkung einer *__slots__*-Deklaration beschränkt sich nicht auf
  die Klasse, in der sie definiert ist. In übergeordneten Klassen
  deklarierte *__slots__* stehen auch in untergeordneten Klassen zur
  Verfügung. Instanzen einer untergeordneten Unterklasse erhalten
  jedoch ein ` "__dict__" ` und ein **__weakref__**, es sei denn, die
  Unterklasse definiert ebenfalls **__slots__** (das nur Namen von
  *zusätzlichen* Slots enthalten sollte).

* Wenn eine Klasse einen Slot definiert, der auch in einer Basisklasse
  definiert ist, ist die durch den Slot der Basisklasse definierte
  Instanzvariable nicht zugänglich (außer durch direktes Abrufen ihres
  Deskriptors aus der Basisklasse). Dies führt dazu, dass das
  Verhalten des Programms undefiniert ist. Möglicherweise wird in
  Zukunft eine Prüfung hinzugefügt, um dies zu verhindern.

* "TypeError" wird ausgelöst, wenn für eine Klasse, die von einem
  "integrierten Typ variabler Länge" abgeleitet ist – etwa "int",
  "bytes" oder "tuple" –, nicht leere *__slots__* definiert sind.

* Jedes nicht-zeichenfolgenartige *iterable* kann *__slots__*
  zugewiesen werden.

* Wenn ein "Wörterbuch" zur Zuweisung von *__slots__* verwendet wird,
  werden die Schlüssel des Wörterbuchs als Slot-Namen verwendet. Die
  Werte des Wörterbuchs können verwendet werden, um attributbezogene
  Docstrings bereitzustellen, die von "inspect.getdoc()" erkannt und
  in der Ausgabe von "help()" angezeigt werden.

* "__class__" Die Zuweisung funktioniert nur, wenn beide Klassen
  dieselben *__slots__* haben.

* Mehrfachvererbung mit mehreren übergeordneten Klassen mit Slots ist
  zulässig, jedoch darf nur eine übergeordnete Klasse durch Slots
  erstellte Attribute enthalten (die anderen Basisklassen müssen leere
  Slot-Layouts aufweisen) – Verstöße führen zu einer „ "TypeError"
  “-Fehlermeldung.

* Wird für *__slots__* ein *Iterator* verwendet, wird für jeden Wert
  des Iterators ein *Deskriptor* erstellt. Das Attribut *__slots__*
  ist jedoch ein leerer Iterator.


3.3.3. Anpassung der Klassenerstellung
--------------------------------------

Immer wenn eine Klasse von einer anderen Klasse erbt, wird die Methode
„ "__init_subclass__()" “ für die übergeordnete Klasse aufgerufen. Auf
diese Weise lassen sich Klassen schreiben, die das Verhalten von
Unterklassen verändern. Dies steht in engem Zusammenhang mit
Klassendekoratoren; während Klassendekoratoren jedoch nur die
jeweilige Klasse beeinflussen, auf die sie angewendet werden, gilt „
"__init_subclass__" “ ausschließlich für zukünftige Unterklassen der
Klasse, die diese Methode definiert.

classmethod object.__init_subclass__(cls)

   Diese Methode wird immer dann aufgerufen, wenn eine Unterklasse der
   übergeordneten Klasse erstellt wird. *cls* ist dann die neue
   Unterklasse. Wenn diese Methode als normale Instanzmethode
   definiert ist, wird sie implizit in eine Klassenmethode
   umgewandelt.

   Schlüsselwortargumente, die einer neuen Klasse übergeben werden,
   werden an die Methode ` "__init_subclass__`" der übergeordneten
   Klasse weitergeleitet. Aus Gründen der Kompatibilität mit anderen
   Klassen, die ` "__init_subclass__`" verwenden, sollte man die
   benötigten Schlüsselwortargumente herausnehmen und die übrigen an
   die Basisklasse weitergeben, wie im folgenden Beispiel:

      Klasse Philosopher:
          def __init_subclass__(cls, /, default_name, **kwargs):
              super().__init_subclass__(**kwargs)
              cls.default_name = default_name

      Klasse AustralianPhilosopher(Philosopher, default_name="Bruce"):
          pass

   Die Standardimplementierung "object.__init_subclass__" führt keine
   Aktion aus, löst jedoch einen Fehler aus, wenn sie mit beliebigen
   Argumenten aufgerufen wird.

   Bemerkung:

     Der Metaklassen-Hinweis „ "metaclass" “ wird vom restlichen
     Typmechanismus verarbeitet und niemals an Implementierungen von „
     "__init_subclass__" “ weitergegeben. Auf die eigentliche
     Metaklasse (und nicht auf den expliziten Hinweis) kann über „
     "type(cls)" “ zugegriffen werden.

   Added in version 3.6.

Wenn eine Klasse erstellt wird, durchsucht „ "type.__new__()" “ die
Klassenvariablen und ruft diejenigen auf, die mit dem Hook „
"__set_name__()" “ versehen sind.

object.__set_name__(self, owner, name)

   Wird automatisch aufgerufen, wenn die Klasse *owner* erstellt wird.
   Das Objekt wurde in dieser Klasse der Variablen *name* zugewiesen:

      Klasse A:
          x = C()  # Ruft automatisch auf: x.__set_name__(A, 'x')

   Wird die Klassenvariable erst nach der Erstellung der Klasse
   zugewiesen, wird „ "__set_name__()" “ nicht automatisch aufgerufen.
   Bei Bedarf kann „ "__set_name__()" “ direkt aufgerufen werden:

      Klasse A:
         pass

      c = C()
      A.x = c                  # Der Hook wird nicht aufgerufen
      c.__set_name__(A, 'x')   # Den Hook manuell aufrufen

   Weitere Informationen findest du unter Erstellen des
   Klassenobjekts.

   Added in version 3.6.


3.3.3.1. Metaklassen
~~~~~~~~~~~~~~~~~~~~

Standardmäßig werden Klassen mithilfe von "type()" erstellt. Der
Klassenkörper wird in einem neuen Namensraum ausgeführt, und der
Klassenname wird lokal an das Ergebnis von "type(name, bases,
namespace)" gebunden.

Der Prozess der Klassenerstellung lässt sich anpassen, indem man in
der Klassendefinition das Schlüsselwortargument „ "metaclass" “
übergibt oder von einer bestehenden Klasse erbt, die ein solches
Argument enthält. Im folgenden Beispiel sind sowohl „ "MyClass" “ als
auch „ "MySubclass" “ Instanzen von „ "Meta" “

   class Meta(type):
       pass

   class MyClass(metaclass=Meta):
       pass

   class MySubclass(MyClass):
       pass

Alle weiteren Schlüsselwortargumente, die in der Klassendefinition
angegeben sind, werden an alle im Folgenden beschriebenen
Metaklassenoperationen weitergeleitet.

Wenn eine Klassendefinition ausgeführt wird, finden folgende Schritte
statt:

* Die MRO-Einträge wurden geklärt;

* die entsprechende Metaklasse wird ermittelt;

* Der Klassen-Namespace wird vorbereitet;

* der Klassenkörper wird ausgeführt;

* Das Klassenobjekt wird erstellt.


3.3.3.2. MRO-Einträge auflösen
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

object.__mro_entries__(self, bases)

   Ist eine Basisklasse, die in einer Klassendefinition auftaucht,
   keine Instanz von "type", wird auf dieser Basis nach einer Methode
   "__mro_entries__()" gesucht. Wird eine "__mro_entries__()"-Methode
   gefunden, wird die Basis beim Erzeugen der Klasse durch das
   Ergebnis eines Aufrufs von "__mro_entries__()" ersetzt. Die Methode
   wird mit dem ursprünglichen Tupel der Basisklassen aufgerufen, das
   dem Parameter *bases* übergeben wurde, und muss ein Tupel von
   Klassen zurückgeben, die anstelle der Basis verwendet werden. Das
   zurückgegebene Tupel darf leer sein; in diesem Fall wird die
   ursprüngliche Basis ignoriert.

Siehe auch:

  "types.resolve_bases()"
     Basisklassen, die keine Instanzen von "type" sind, dynamisch
     auflösen.

  "types.get_original_bases()"
     Die „ursprünglichen Basen“ einer Klasse vor den Änderungen durch
     "__mro_entries__()" abrufen.

  **PEP 560**
     Grundlegende Unterstützung für das Typmodul und generische Typen.


3.3.3.3. Ermittlung der geeigneten Metaklasse
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Die passende Metaklasse für eine Klassendefinition wird wie folgt
ermittelt:

* Wenn keine Basisklassen und keine explizite Metaklasse angegeben
  sind, wird „ "type()" “ verwendet;

* Wenn eine explizite Metaklasse angegeben wird und diese *keine*
  Instanz von "type()" ist, wird sie direkt als Metaklasse verwendet;

* Wird eine Instanz von ` "type()" ` als explizite Metaklasse
  angegeben oder sind Basisklassen definiert, wird die am weitesten
  abgeleitete Metaklasse verwendet.

Die am weitesten abgeleitete Metaklasse wird aus der explizit
angegebenen Metaklasse (sofern vorhanden) und den Metaklassen (d.h.
"type(cls)") aller angegebenen Basisklassen ausgewählt. Die am
weitesten abgeleitete Metaklasse ist jene, die ein Untertyp von
*allen* diesen in Frage kommenden Metaklassen ist. Erfüllt keine der
in Frage kommenden Metaklassen dieses Kriterium, schlägt die
Klassendefinition mit der Fehlermeldung „ "TypeError" “ fehl.


3.3.3.4. Vorbereiten des Klassen-Namespace
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sobald die entsprechende Metaklasse identifiziert wurde, wird der
Klassen-Namespace vorbereitet. Verfügt die Metaklasse über ein
Attribut „ "__prepare__" “, wird diese als ` "namespace =
metaclass.__prepare__(name, bases, **kwds)" ` aufgerufen (wobei
etwaige zusätzliche Schlüsselwortargumente aus der Klassendefinition
stammen). Die Methode ` "__prepare__" ` sollte als "classmethod"
implementiert werden. Der von ` "__prepare__" ` zurückgegebene
Namensraum wird an ` "__new__`" übergeben, doch beim Erstellen des
endgültigen Klassenobjekts wird der Namensraum in ein neues ` "dict`"
kopiert.

Verfügt die Metaklasse nicht über das Attribut „ "__prepare__" “, wird
der Klassennamensraum als leere geordnete Zuordnung initialisiert.

Siehe auch:

  **PEP 3115** - Metaklassen in Python 3000
     Einführung des Namespace-Hooks „ "__prepare__" “


3.3.3.5. Ausführen des Klassenkörpers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Der Klassenkörper wird (ungefähr) wie folgt ausgeführt: ` "exec(body,
globals(), namespace)`". Der wesentliche Unterschied zu einem normalen
Aufruf von ` "exec()" ` besteht darin, dass der Klassenkörper
(einschließlich aller Methoden) aufgrund der lexikalischen
Gültigkeitsbereiche auf Namen aus dem aktuellen und den äußeren
Gültigkeitsbereichen verweisen kann, wenn die Klassendefinition
innerhalb einer Funktion steht.

Doch selbst wenn die Klassendefinition innerhalb der Funktion steht,
können die innerhalb der Klasse definierten Methoden dennoch nicht auf
Namen zugreifen, die im Klassenbereich definiert sind. Der Zugriff auf
Klassenvariablen muss über den ersten Parameter von Instanz- oder
Klassenmethoden erfolgen oder über die implizite, lexikalisch
begrenzte Referenz „ "__class__" “, die im nächsten Abschnitt
beschrieben wird.


3.3.3.6. Erstellen des Klassenobjekts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sobald der Klassen-Namespace durch die Ausführung des Klassenkörpers
gefüllt wurde, wird das Klassenobjekt durch den Aufruf von „
"metaclass(name, bases, namespace, **kwds)" “ erstellt (die hier
übergebenen zusätzlichen Schlüsselwörter sind dieselben wie die, die
an „ "__prepare__" “ übergeben werden).

Dieses Klassenobjekt ist dasjenige, auf das sich die argumentlose Form
von "super()" bezieht. "__class__" ist ein impliziter Closure-Verweis,
den der Compiler erzeugt, sobald eine Methode im Klassenkörper
entweder "__class__" oder "super" verwendet. Dadurch kann die
argumentlose Form von "super()" die gerade definierte Klasse anhand
des lexikalischen Gültigkeitsbereichs korrekt bestimmen, während die
Klasse oder Instanz, über die der aktuelle Aufruf erfolgt ist, anhand
des ersten an die Methode übergebenen Arguments ermittelt wird.

In CPython 3.6 und höher wird die Zelle „ "__class__" “ als Eintrag
unter „ "__classcell__" “ im Klassennamensraum an die Metaklasse
übergeben. Sofern vorhanden, muss dieser Eintrag bis zum Aufruf von „
"type.__new__" “ weitergegeben werden, damit die Klasse korrekt
initialisiert wird. Andernfalls kommt es in Python 3.8 zu einem „
"RuntimeError" “.

Bei Verwendung der Standard-Metaklasse „ "type" “ oder einer
beliebigen Metaklasse, die letztendlich „ "type.__new__" “ aufruft,
werden nach der Erstellung des Klassenobjekts die folgenden
zusätzlichen Anpassungsschritte ausgeführt:

1. Die Methode „ "type.__new__" “ sammelt alle Attribute im Klassen-
   Namespace, die eine „ "__set_name__()" “-Methode definieren;

2. Diese Methoden „ "__set_name__" “ werden mit der zu definierenden
   Klasse und dem zugewiesenen Namen des jeweiligen Attributs
   aufgerufen;

3. Der Hook „ "__init_subclass__()" “ wird für den unmittelbaren
   übergeordneten Elternteil der neuen Klasse gemäß dessen
   Methodenauflösungsreihenfolge aufgerufen.

Nachdem das Klassenobjekt erstellt wurde, wird es an die in der
Klassendefinition enthaltenen Klassendekoratoren (sofern vorhanden)
übergeben, und das resultierende Objekt wird im lokalen Namensraum als
die definierte Klasse gebunden.

Wenn eine neue Klasse mit ` "type.__new__`" erstellt wird, wird das
als Namespace-Parameter angegebene Objekt in eine neue geordnete
Zuordnung kopiert und das ursprüngliche Objekt verworfen. Die neue
Kopie wird in einen schreibgeschützten Proxy verpackt, der zum
Attribut ` "__dict__" ` des Klassenobjekts wird.

Siehe auch:

  **PEP 3135** - Neuer Super
     Beschreibt die implizite Referenz auf die Closure „ "__class__" “


3.3.3.7. Anwendungsbereiche von Metaklassen
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Die Einsatzmöglichkeiten von Metaklassen sind grenzenlos. Zu den
bereits untersuchten Ideen zählen Enums, Protokollierung,
Schnittstellenprüfung, automatische Delegierung, automatische
Eigenschaftserstellung, Proxys, Frameworks sowie automatische
Ressourcensperrung und -synchronisation.


3.3.4. Anpassung der Instanz- und Unterklassenprüfungen
-------------------------------------------------------

Die folgenden Methoden dienen dazu, das Standardverhalten der
integrierten Funktionen „ "isinstance()" “ und „ "issubclass()" “ zu
überschreiben.

Insbesondere implementiert die Metaklasse „ "abc.ABCMeta" “ diese
Methoden, um das Hinzufügen von abstrakten Basisklassen (ABCs) als
„virtuelle Basisklassen“ zu beliebigen Klassen oder Typen
(einschließlich integrierter Typen) zu ermöglichen, darunter auch
andere ABCs.

type.__instancecheck__(self, instance)

   Gibt „true“ zurück, wenn *instance* als (direkte oder indirekte)
   Instanz von *class* betrachtet werden soll. Falls definiert, wird
   diese Funktion zur Implementierung von ` "isinstance(instance,
   class)`" aufgerufen.

type.__subclasscheck__(self, subclass)

   Gibt „true“ zurück, wenn *subclass* als (direkte oder indirekte)
   Unterklasse von *class* betrachtet werden soll. Falls definiert,
   wird diese Funktion zur Implementierung von ` "issubclass(subclass,
   class)`" aufgerufen.

Beachten Sie, dass diese Methoden anhand des Typs (der Metaklasse)
einer Klasse nachgeschlagen werden. Sie können nicht als
Klassenmethoden in der eigentlichen Klasse definiert werden. Dies
entspricht dem Nachschlagen spezieller Methoden, die auf Instanzen
aufgerufen werden, nur dass in diesem Fall die Instanz selbst eine
Klasse ist.

Siehe auch:

  **PEP 3119** - Einführung in abstrakte Basisklassen
     Enthält die Spezifikation zur Anpassung des Verhaltens von
     "isinstance()" und "issubclass()" über "__instancecheck__()" und
     "__subclasscheck__()", einschließlich der Begründung für diese
     Möglichkeit im Zusammenhang mit der Aufnahme abstrakter
     Basisklassen (siehe das Modul "abc") in die Sprache.


3.3.5. Emulation generischer Typen
----------------------------------

Bei der Verwendung von *Typ-Annotationen* ist es oft sinnvoll, einen
*generischen Typ* mithilfe der Python-Notation mit eckigen Klammern zu
*parametrisieren*. Beispielsweise könnte die Annotation "list[int]"
verwendet werden, um eine "list" zu bezeichnen, in der alle Elemente
vom Typ "int" sind.

Siehe auch:

  **PEP 484** - Typ-Hinweise
     Einführung in das Python-Framework für Typangaben

  Generische Alias-Typen
     Dokumentation zu Objekten, die parametrisierte generische Klassen
     darstellen

  Generics, benutzerdefinierte Generika und "typing.Generic"
     Dokumentation zur Implementierung generischer Klassen, die zur
     Laufzeit parametrisiert werden können und von statischen
     Typprüfern erkannt werden.

Eine Klasse kann *im Allgemeinen* nur dann parametrisiert werden, wenn
sie die spezielle Klassenmethode „ "__class_getitem__()" “ definiert.

classmethod object.__class_getitem__(cls, key)

   Gibt ein Objekt zurück, das die Spezialisierung einer generischen
   Klasse anhand der in *key* enthaltenen Typargumente darstellt.

   Wenn „ "__class_getitem__()" “ in einer Klasse definiert wird, ist
   es automatisch eine Klassenmethode. Daher muss es bei der
   Definition nicht mit „ "@classmethod" “ versehen werden.


3.3.5.1. Der Zweck von *__class_getitem__*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Der Zweck von "__class_getitem__()" besteht darin, die
Parametrisierung generischer Klassen der Standardbibliothek zur
Laufzeit zu ermöglichen, um *Typangaben* einfacher auf diese Klassen
anwenden zu können.

Um benutzerdefinierte generische Klassen zu implementieren, die zur
Laufzeit parametrisiert werden können und von statischen Typprüfern
erkannt werden, sollten Benutzer entweder von einer Klasse der
Standardbibliothek erben, die bereits „ "__class_getitem__()" “
implementiert, oder von „ "typing.Generic" “ erben, das über eine
eigene Implementierung von „ "__class_getitem__()" “ verfügt.

Benutzerdefinierte Implementierungen von ` "__class_getitem__()" ` für
Klassen, die außerhalb der Standardbibliothek definiert sind, werden
von Typprüfprogrammen von Drittanbietern wie mypy möglicherweise nicht
erkannt. Von der Verwendung von ` "__class_getitem__()" ` für
beliebige Klassen zu anderen Zwecken als der Typangabe wird abgeraten.


3.3.5.2. *__class_getitem__* im Vergleich zu *__getitem__*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Normalerweise ruft die subscription eines Objekts in eckigen Klammern
die Instanzmethode „ "__getitem__()" “ auf, die in der Klasse des
Objekts definiert ist. Ist das Objekt, für das ein Abonnement erstellt
wird, jedoch selbst eine Klasse, wird stattdessen möglicherweise die
Klassenmethode „ "__class_getitem__()" “ aufgerufen. „
"__class_getitem__()" “ sollte ein „ GenericAlias “-Objekt
zurückgeben, sofern es ordnungsgemäß definiert ist.

Wenn dem Python-Interpreter der *Ausdruck* "obj[x]" übergeben wird,
durchläuft er in etwa den folgenden Ablauf, um zu entscheiden, ob
"__getitem__()" oder "__class_getitem__()" aufgerufen werden soll:

   from inspect import isclass

   def subscribe(obj, x):
       """Gibt das Ergebnis des Ausdrucks 'obj[x]' zurück"""

       class_of_obj = type(obj)

       # Wenn die Klasse von obj __getitem__ definiert,
       # dann rufe class_of_obj.__getitem__(obj, x) auf
       if hasattr(class_of_obj, '__getitem__'):
           return class_of_obj.__getitem__(obj, x)

       # Andernfalls, wenn `obj` eine Klasse ist und `__class_getitem__` definiert,
       # `obj.__class_getitem__(x)` aufrufen
       elif isclass(obj) and hasattr(obj, '__class_getitem__'):
           return obj.__class_getitem__(x)

       # Andernfalls eine Ausnahme auslösen
       else:
           raise TypeError(
               f"'{class_of_obj.__name__}' ist kein indizierbares Objekt"
           )

In Python sind alle Klassen selbst Instanzen anderer Klassen. Die
Klasse einer Klasse wird als deren *Metaklasse* bezeichnet, und die
meisten Klassen haben die Klasse „ "type" “ als Metaklasse. „ "type" “
definiert keine „ "__getitem__()" “, was bedeutet, dass Ausdrücke wie
„ "list[int]" “, „ "dict[str, float]" “ und „ "tuple[str, bytes]" “
alle dazu führen, dass „ "__class_getitem__()" “ aufgerufen wird:

   >>> # List hat Klasse "type" als seine Metaklasse, wie die meisten Klasse:
   >>> type(list)
   <class 'type'>
   >>> type(dict) == type(list) == type(tuple) == type(str) == type(bytes)
   True
   >>> # "list[int]" calls "list.__class_getitem__(int)"
   >>> list[int]
   list[int]
   >>> # list.__class_getitem__ returns a GenericAlias object:
   >>> type(list[int])
   <class 'types.GenericAlias'>

Wenn eine Klasse jedoch über eine benutzerdefinierte Metaklasse
verfügt, die „ "__getitem__()" “ definiert, kann das Abonnieren der
Klasse zu einem abweichenden Verhalten führen. Ein Beispiel hierfür
findet sich im Modul „ "enum" “:

   >>> from enum import Enum
   >>> class Menu(Enum):
   ...     """Ein Frühstücksmenü"""
   ...     SPAM = 'spam'
   ...     BACON = 'bacon'
   ...
   >>> # Enum-Klassen verfügen über eine benutzerdefinierte Metaklasse:
   >>> type(Menu)
   <class 'enum.EnumMeta'>
   >>> # EnumMeta definiert __getitem__,
   >>> # daher wird __class_getitem__ nicht aufgerufen,
   >>> # und das Ergebnis ist kein GenericAlias-Objekt:
   >>> Menu['SPAM']<Menu.SPAM: 'spam'>
   >>> type(Menu['SPAM'])
   <enum 'Menu'>

Siehe auch:

  **PEP 560** - Kernunterstützung für das Typisierungsmodul und
  generische Typen
     Vorstellung von „ "__class_getitem__()" “ und Erläuterung, wann
     ein „ subscription “ dazu führt, dass „ "__class_getitem__()" “
     aufgerufen wird, anstatt "__getitem__()"


3.3.6. Aufrufbare Objekte emulieren
-----------------------------------

object.__call__(self[, args...])

   Wird aufgerufen, wenn die Instanz als Funktion „aufgerufen“ wird;
   ist diese Methode definiert, entspricht „ "x(arg1, arg2, ...)" “ in
   etwa „ "type(x).__call__(x, arg1, ...)" “. Die Klasse „ "object" “
   selbst stellt diese Methode nicht zur Verfügung.


3.3.7. Containertypen emulieren
-------------------------------

Zur Implementierung von Container-Objekten können die folgenden
Methoden definiert werden. Keine davon wird von der Klasse "object"
selbst bereitgestellt. Container sind in der Regel *Sequenzen* (etwa
"Listen" oder "Tupel") oder *Mappings* (wie *Dictionarys*), können
aber auch andere Container darstellen. Die erste Gruppe von Methoden
dient entweder der Nachbildung einer Sequenz oder der Nachbildung
eines Mappings; der Unterschied besteht darin, dass bei einer Sequenz
die zulässigen Schlüssel die ganzen Zahlen *k* sein sollten, für die
"0 <= k < N" gilt, wobei *N* die Länge der Sequenz ist, oder Objekte
vom Typ "slice", die einen Bereich von Elementen definieren. Es wird
außerdem empfohlen, dass Mappings die Methoden "keys()", "values()",
"items()", "get()", "clear()", "setdefault()", "pop()", "popitem()",
"copy()" und "update()" bereitstellen, die sich ähnlich verhalten wie
die der Python-Standardobjekte vom Typ "Dictionary". Das Modul
"collections.abc" stellt die *abstrakte Basisklasse* "MutableMapping"
bereit, um die Erstellung dieser Methoden ausgehend von einem
Basissatz aus "__getitem__()", "__setitem__()", "__delitem__()" und
"keys()" zu erleichtern.

Veränderbare Sequenzen sollten Methoden Veränderbare Sequenzen sollten
die Methoden "append()", "clear()", "count()", "extend()", "index()",
"insert()", "pop()", "remove()" und "reverse()" bereitstellen, so wie
die Standard-"list"-Objekte von Python. Schließlich sollten
Sequenztypen die Addition (im Sinne von Verkettung) und die
Multiplikation (im Sinne von Wiederholung) umsetzen, indem sie die
unten beschriebenen Methoden "__add__()", "__radd__()", "__iadd__()",
"__mul__()", "__rmul__()" und "__imul__()" definieren; andere
numerische Operatoren sollten sie nicht definieren.

Es wird empfohlen, dass sowohl Mappings als auch Sequenzen die Methode
` "__contains__()" ` implementieren, um eine effiziente Nutzung des
Operators ` "in" ` zu ermöglichen; bei Mappings sollte ` "in" ` die
Schlüssel des Mappings durchsuchen, bei Sequenzen hingegen die Werte.
Es wird ferner empfohlen, dass sowohl Mappings als auch Sequenzen die
Methode „ "__iter__()" “ implementieren, um eine effiziente Iteration
durch den Container zu ermöglichen; bei Mappings sollte „ "__iter__()"
“ die Schlüssel des Objekts durchlaufen; bei Sequenzen sollte sie die
Werte durchlaufen.

object.__len__(self)

   Wird aufgerufen, um die integrierte Funktion "len()" umzusetzen.
   Sollte die Länge des Objekts zurückgeben, eine ganze Zahl ">=" 0.
   Außerdem gilt ein Objekt, das keine Methode "__bool__()" definiert
   und dessen Methode "__len__()" null zurückgibt, in einem booleschen
   Kontext als falsch.

   In CPython darf die Länge höchstens "sys.maxsize" betragen. Ist die
   Länge größer als "sys.maxsize", kann es bei einigen Funktionen (wie
   z. B. "len()") zu einem "OverflowError" kommen. Um zu verhindern,
   dass durch die Überprüfung des Wahrheitswerts ein "OverflowError"
   ausgelöst wird, muss ein Objekt eine "__bool__()" -Methode
   definieren.

object.__length_hint__(self)

   Wird aufgerufen, um "operator.length_hint()" umzusetzen. Sollte
   eine geschätzte Länge für das Objekt zurückgeben, die größer oder
   kleiner als die tatsächliche Länge sein darf. Die Länge muss eine
   ganze Zahl ">=" 0 sein. Der Rückgabewert darf auch "NotImplemented"
   sein, was genauso behandelt wird, als gäbe es die Methode
   "__length_hint__" überhaupt nicht. Diese Methode dient
   ausschließlich der Optimierung und ist für die Korrektheit nie
   erforderlich.

   Added in version 3.4.

Bemerkung:

  Slicing is done exclusively with the following three methods.  A
  call like

     a[1:2] = b

  wird übersetzt zu

     a[slice(1, 2, None)] = b

  and so forth.  Missing slice items are always filled in with "None".

object.__getitem__(self, key)

   Called to implement evaluation of "self[key]". For *sequence*
   types, the accepted keys should be integers. Optionally, they may
   support "slice" objects as well.  Negative index support is also
   optional. If *key* is of an inappropriate type, "TypeError" may be
   raised; if *key* is a value outside the set of indexes for the
   sequence (after any special interpretation of negative values),
   "IndexError" should be raised. For *mapping* types, if *key* is
   missing (not in the container), "KeyError" should be raised.

   Bemerkung:

     "for" loops expect that an "IndexError" will be raised for
     illegal indexes to allow proper detection of the end of the
     sequence.

   Bemerkung:

     When subscripting a *class*, the special class method
     "__class_getitem__()" may be called instead of "__getitem__()".
     See __class_getitem__ im Vergleich zu __getitem__ for more
     details.

object.__setitem__(self, key, value)

   Wird aufgerufen, um die Zuweisung an "self[key]" umzusetzen. Es
   gilt dieselbe Anmerkung wie bei "__getitem__()". Diese Methode
   sollte bei Mappings nur dann implementiert werden, wenn die Objekte
   das Ändern der Werte zu Schlüsseln unterstützen oder neue Schlüssel
   hinzugefügt werden können, und bei Sequenzen nur dann, wenn
   Elemente ersetzt werden können. Bei unzulässigen Werten für *key*
   sollten dieselben Ausnahmen ausgelöst werden wie bei der Methode
   "__getitem__()".

object.__delitem__(self, key)

   Wird aufgerufen, um das Löschen von "self[key]" umzusetzen. Es gilt
   dieselbe Anmerkung wie bei "__getitem__()". Diese Methode sollte
   bei Mappings nur dann implementiert werden, wenn die Objekte das
   Entfernen von Schlüsseln unterstützen, und bei Sequenzen nur dann,
   wenn Elemente aus der Sequenz entfernt werden können. Bei
   unzulässigen Werten für *key* sollten dieselben Ausnahmen ausgelöst
   werden wie bei der Methode "__getitem__()".

object.__missing__(self, key)

   Wird von "dict"."__getitem__()" aufgerufen, um "self[key]" für
   Unterklassen von dict zu implementieren, wenn der Schlüssel nicht
   im Wörterbuch enthalten ist.

object.__iter__(self)

   Diese Methode wird aufgerufen, wenn für einen Container ein
   *Iterator* benötigt wird. Diese Methode sollte ein neues Iterator-
   Objekt zurückgeben, mit dem alle Objekte im Container durchlaufen
   werden können. Bei Mappings sollte sie die Schlüssel des Containers
   durchlaufen.

object.__reversed__(self)

   Wird (sofern vorhanden) von der integrierten Funktion „
   "reversed()" “ aufgerufen, um die umgekehrte Iteration zu
   implementieren. Die Funktion sollte ein neues Iterator-Objekt
   zurückgeben, das alle Objekte im Container in umgekehrter
   Reihenfolge durchläuft.

   Wenn die Methode „ "__reversed__()" “ nicht bereitgestellt wird,
   greift die integrierte Funktion „ "reversed()" “ auf das
   Sequenzprotokoll zurück ("__len__()" und "__getitem__()"). Objekte,
   die das Sequenzprotokoll unterstützen, sollten „ "__reversed__()" “
   nur dann bereitstellen, wenn sie eine Implementierung bieten
   können, die effizienter ist als die von "reversed()"
   bereitgestellte.

Die Operatoren zur Überprüfung der Mitgliedschaft ("in" und "not in")
werden normalerweise als Iteration durch einen Container
implementiert. Container-Objekte können jedoch die folgende spezielle
Methode mit einer effizienteren Implementierung bereitstellen, für die
das Objekt zudem nicht iterierbar sein muss.

object.__contains__(self, item)

   Aufruf zur Implementierung von Operatoren zur Überprüfung der
   Mitgliedschaft.  Sollte „true“ zurückgeben, wenn *item* in *self*
   enthalten ist, andernfalls „false“.  Bei Mapping-Objekten sollten
   dabei die Schlüssel des Mappings berücksichtigt werden und nicht
   die Werte oder die Schlüssel-Wert-Paare.

   Bei Objekten, die "__contains__()" nicht definieren, versucht der
   Mitgliedschaftstest zuerst die Iteration über "__iter__()" und dann
   das alte Sequenz-Iterationsprotokoll über "__getitem__()"; siehe
   diesen Abschnitt der Sprachreferenz.


3.3.8. Emulation numerischer Datentypen
---------------------------------------

Die folgenden Methoden können definiert werden, um numerische Objekte
zu emulieren. Methoden, die Operationen entsprechen, die von dem
jeweiligen implementierten Zahlentyp nicht unterstützt werden (z. B.
bitweise Operationen für nicht-ganzzahlige Zahlen), sollten
undefiniert bleiben.

object.__add__(self, other)
object.__sub__(self, other)
object.__mul__(self, other)
object.__matmul__(self, other)
object.__truediv__(self, other)
object.__floordiv__(self, other)
object.__mod__(self, other)
object.__divmod__(self, other)
object.__pow__(self, other[, modulo])
object.__lshift__(self, other)
object.__rshift__(self, other)
object.__and__(self, other)
object.__xor__(self, other)
object.__or__(self, other)

   These methods are called to implement the binary arithmetic
   operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",
   "pow()", "**", "<<", ">>", "&", "^", "|").  For instance, to
   evaluate the expression "x + y", where *x* is an instance of a
   class that has an "__add__()" method, "type(x).__add__(x, y)" is
   called.  The "__divmod__()" method should be the equivalent to
   using "__floordiv__()" and "__mod__()"; it should not be related to
   "__truediv__()".  Note that "__pow__()" should be defined to accept
   an optional third argument if the ternary version of the built-in
   "pow()" function is to be supported.

   Wenn eine dieser Methoden die Operation mit den übergebenen
   Argumenten nicht unterstützt, sollte sie "NotImplemented"
   zurückgeben.

object.__radd__(self, other)
object.__rsub__(self, other)
object.__rmul__(self, other)
object.__rmatmul__(self, other)
object.__rtruediv__(self, other)
object.__rfloordiv__(self, other)
object.__rmod__(self, other)
object.__rdivmod__(self, other)
object.__rpow__(self, other[, modulo])
object.__rlshift__(self, other)
object.__rrshift__(self, other)
object.__rand__(self, other)
object.__rxor__(self, other)
object.__ror__(self, other)

   These methods are called to implement the binary arithmetic
   operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",
   "pow()", "**", "<<", ">>", "&", "^", "|") with reflected (swapped)
   operands.  These functions are only called if the left operand does
   not support the corresponding operation [3] and the operands are of
   different types. [4] For instance, to evaluate the expression "x -
   y", where *y* is an instance of a class that has an "__rsub__()"
   method, "type(y).__rsub__(y, x)" is called if "type(x).__sub__(x,
   y)" returns "NotImplemented".

   Note that ternary "pow()" will not try calling "__rpow__()" (the
   coercion rules would become too complicated).

   Bemerkung:

     Wenn der Typ des rechten Operanden eine Unterklasse des Typs des
     linken Operanden ist und diese Unterklasse eine andere
     Implementierung der reflektierten Methode für die Operation
     bereitstellt, wird diese Methode vor der nicht reflektierten
     Methode des linken Operanden aufgerufen. Dieses Verhalten
     ermöglicht es Unterklassen, die Operationen ihrer Vorfahren zu
     überschreiben.

object.__iadd__(self, other)
object.__isub__(self, other)
object.__imul__(self, other)
object.__imatmul__(self, other)
object.__itruediv__(self, other)
object.__ifloordiv__(self, other)
object.__imod__(self, other)
object.__ipow__(self, other[, modulo])
object.__ilshift__(self, other)
object.__irshift__(self, other)
object.__iand__(self, other)
object.__ixor__(self, other)
object.__ior__(self, other)

   Diese Methoden werden aufgerufen, um die erweiterten arithmetischen
   Zuweisungen zu implementieren ("+=", "-=", "*=", "@=", "/=", "//=",
   "%=", "**=", "<<=", ">>=", "&=", "^=", "|="). Diese Methoden
   sollten versuchen, die Operation an Ort und Stelle durchzuführen
   (indem sie *self* ändern) und das Ergebnis zurückzugeben (das
   *self* sein kann, aber nicht muss).  Ist eine bestimmte Methode
   nicht definiert oder gibt diese Methode „ "NotImplemented" “
   zurück, greift die erweiterte Zuweisung auf die normalen Methoden
   zurück.  Ist beispielsweise *x* eine Instanz einer Klasse mit einer
   Methode „ "__iadd__()" “, so ist „ "x += y" “ gleichbedeutend mit „
   "x = x.__iadd__(y)" “. Existiert „ "__iadd__()" “ nicht oder gibt „
   "x.__iadd__(y)" “ „ "NotImplemented" “ zurück, werden „
   "x.__add__(y)" “ und „ "y.__radd__(x)" “ berücksichtigt, wie bei
   der Auswertung von „ "x + y" “. In bestimmten Situationen kann die
   erweiterte Zuweisung zu unerwarteten Fehlern führen (siehe Why does
   a_tuple[i] += ['item'] raise an exception when the addition
   works?), doch dieses Verhalten ist tatsächlich Teil des
   Datenmodells.

object.__neg__(self)
object.__pos__(self)
object.__abs__(self)
object.__invert__(self)

   Wird aufgerufen, um die unären arithmetischen Operationen zu
   implementieren ("-", "+", "abs()" und "~").

object.__complex__(self)
object.__int__(self)
object.__float__(self)

   Wird aufgerufen, um die integrierten Funktionen „ "complex()" “, „
   "int()" “ und „ "float()" “ zu implementieren. Sollte einen Wert
   des entsprechenden Typs zurückgeben.

object.__index__(self)

   Wird aufgerufen, um "operator.index()" zu implementieren, sowie
   immer dann, wenn Python das numerische Objekt verlustfrei in ein
   Ganzzahlobjekt konvertieren muss (z. B. beim Slicing oder in den
   integrierten Funktionen "bin()", "hex()" und "oct()"). Das
   Vorhandensein dieser Methode weist darauf hin, dass das numerische
   Objekt vom Typ Ganzzahl ist. Muss eine Ganzzahl zurückgeben.

   Wenn "__int__()", "__float__()" und "__complex__()" nicht definiert
   sind, greifen die entsprechenden integrierten Funktionen "int()",
   "float()" und "complex()" auf "__index__()" zurück.

object.__round__(self[, ndigits])
object.__trunc__(self)
object.__floor__(self)
object.__ceil__(self)

   Wird aufgerufen, um die integrierten Funktionen "round()" und
   "math" sowie die Funktionen "trunc()", "floor()" und "ceil()" zu
   implementieren. Sofern nicht *ndigits* an "__round__()" übergeben
   wird, sollten alle diese Methoden den Wert des Objekts zurückgeben,
   gekürzt auf ein "Integral" (in der Regel ein "int").

   The built-in function "int()" falls back to "__trunc__()" if
   neither "__int__()" nor "__index__()" is defined.

   Geändert in Version 3.11: The delegation of "int()" to
   "__trunc__()" is deprecated.


3.3.9. Mit Statement-Kontextmanagern
------------------------------------

Ein *Kontextmanager* ist ein Objekt, das den Laufzeittkontext
definiert, der bei der Ausführung einer "with" -Anweisung eingerichtet
werden soll. Der Kontextmanager verwaltet den Eintritt in und den
Austritt aus dem gewünschten Laufzeittkontext für die Ausführung des
Codeblocks. Kontextmanager werden normalerweise mit der Anweisung „
"with" “ aufgerufen (beschrieben im Abschnitt Die Erklärung von with
.), können aber auch durch direkten Aufruf ihrer Methoden verwendet
werden.

Zu den typischen Anwendungsbereichen von Kontextmanagern gehören das
Speichern und Wiederherstellen verschiedener Arten von globalem
Status, das Sperren und Entsperren von Ressourcen, das Schließen
geöffneter Dateien usw.

Weitere Informationen zu Kontextmanagern findest du unter Kontext-
Manager-Typen. Die Klasse „ "object" “ selbst stellt keine
Kontextmanager-Methoden bereit.

object.__enter__(self)

   Gib den Laufzeitkontext ein, der sich auf dieses Objekt bezieht.
   Die Anweisung „ "with" “ bindet den Rückgabewert dieser Methode an
   die in der Klausel „ "as" “ der Anweisung angegebenen Ziele, sofern
   vorhanden.

object.__exit__(self, exc_type, exc_value, traceback)

   Verlasse den mit diesem Objekt verbundenen Laufzeittkontext. Die
   Parameter beschreiben die Ausnahme, die zum Verlassen des Kontexts
   geführt hat. Wurde der Kontext ohne Ausnahme verlassen, sind alle
   drei Argumente "None".

   Wenn eine Ausnahme übergeben wird und die Methode diese Ausnahme
   unterdrücken möchte (d.h. verhindern möchte, dass sie
   weitergeleitet wird), sollte sie einen wahren Wert zurückgeben.
   Andernfalls wird die Ausnahme beim Verlassen dieser Methode wie
   gewohnt verarbeitet.

   Beachten Sie, dass Methoden von ` "__exit__()" ` die übergebene
   Ausnahme nicht erneut auslösen sollten; dies liegt in der
   Verantwortung des Aufrufers.

Siehe auch:

  **PEP 343** - Die „with“-Anweisung
     Die Spezifikation, Hintergründe und Beispiele zur Python-
     Anweisung „ "with" “.


3.3.10. Anpassen von Positionsargumenten beim Klassenmusterabgleich
-------------------------------------------------------------------

Bei der Verwendung eines Klassennamens in einem Muster sind
Positionsargumente im Muster standardmäßig nicht zulässig, d.h. `
"case MyClass(x, y)" ` ist in der Regel ungültig, sofern keine
spezielle Unterstützung in ` "MyClass`" vorhanden ist. Um ein solches
Muster verwenden zu können, muss die Klasse ein Attribut
**__match_args__** definieren.

object.__match_args__

   Dieser Klassenvariablen kann ein Tupel aus Zeichenketten zugewiesen
   werden. Wenn diese Klasse in einem Klassenmuster mit
   Positionsargumenten verwendet wird, wird jedes Positionsargument in
   ein Schlüsselwortargument umgewandelt, wobei der entsprechende Wert
   in *__match_args__* als Schlüsselwort verwendet wird. Das Fehlen
   dieses Attributs entspricht der Einstellung „ "()" “.

Wenn beispielsweise "MyClass.__match_args__" gleich "("left",
"center", "right")" ist, bedeutet dies, dass "case MyClass(x, y)"
gleichbedeutend mit "case MyClass(left=x, center=y)" ist. Beachten
Sie, dass die Anzahl der Argumente im Muster kleiner oder gleich der
Anzahl der Elemente in *__match_args__* sein muss; ist sie größer,
löst der Versuch der Musterabgleichung einen "TypeError" aus.

Added in version 3.10.

Siehe auch:

  **PEP 634** - Struktureller Musterabgleich
     Die Spezifikation für die Python-Anweisung „ "match" “.


3.3.11. Puffertypen emulieren
-----------------------------

Das Buffer-Protokoll bietet Python-Objekten die Möglichkeit, einen
effizienten Zugriff auf ein Low-Level-Speicherarray zu ermöglichen.
Dieses Protokoll wird von integrierten Typen wie "bytes" und
"memoryview" implementiert, und Bibliotheken von Drittanbietern können
zusätzliche Buffer-Typen definieren.

Zwar werden Puffertypen in der Regel in C implementiert, doch ist es
auch möglich, das Protokoll in Python zu implementieren.

object.__buffer__(self, flags)

   Wird aufgerufen, wenn ein Puffer von *self* angefordert wird
   (beispielsweise durch den Konstruktor „ "memoryview" “). Das
   Argument *flags* ist eine Ganzzahl, die die Art des angeforderten
   Puffers angibt und beispielsweise beeinflusst, ob der
   zurückgegebene Puffer schreibgeschützt oder beschreibbar ist. Die
   Funktion „ "inspect.BufferFlags" “ bietet eine bequeme Möglichkeit,
   die Flags zu interpretieren. Die Methode muss ein „ "memoryview"
   “-Objekt zurückgeben.

object.__release_buffer__(self, buffer)

   Called when a buffer is no longer needed. The *buffer* argument is
   a "memoryview" object that was previously returned by
   "__buffer__()". The method must release any resources associated
   with the buffer. This method should return "None". Buffer objects
   that do not need to perform any cleanup are not required to
   implement this method.

Added in version 3.12.

Siehe auch:

  **PEP 688** - Das Pufferprotokoll in Python verfügbar machen
     Stellt die Python-Methoden „ "__buffer__" “ und „
     "__release_buffer__" “ vor.

  "collections.abc.Buffer"
     Das ABC der Puffertypen.


3.3.12. Suche nach speziellen Methoden
--------------------------------------

Bei benutzerdefinierten Klassen ist die korrekte Funktion impliziter
Aufrufe spezieller Methoden nur dann gewährleistet, wenn diese im Typ
des Objekts definiert sind, nicht jedoch im Instanz-Wörterbuch des
Objekts. Dieses Verhalten ist der Grund dafür, dass der folgende Code
eine Ausnahme auslöst:

   >>> class C:
   ...     pass
   ...
   >>> c = C()
   >>> c.__len__ = lambda: 5
   >>> len(c)
   Traceback (letzter Aufruf zuletzt):
     Datei „<stdin> “, Zeile 1, in <module>
   TypeError: Objekt vom Typ „C“ hat keine len()-Methode

Der Grund für dieses Verhalten liegt in einer Reihe spezieller
Methoden wie „ "__hash__()" “ und „ "__repr__()" “, die von allen
Objekten, einschließlich Typobjekten, implementiert werden. Würde bei
der impliziten Suche nach diesen Methoden der herkömmliche Suchvorgang
verwendet, würden sie fehlschlagen, wenn sie auf das Typobjekt selbst
aufgerufen würden:

   >>> 1 .__hash__() == hash(1)
   True
   >>> int.__hash__() == hash(int)
   Traceback (letzter Aufruf zuletzt):
     Datei „<stdin> “, Zeile 1, in <module>
   TypeError: Der Deskriptor „__hash__“ des Objekts „int“ benötigt ein Argument

Der fehlerhafte Versuch, eine nicht gebundene Methode einer Klasse auf
diese Weise aufzurufen, wird manchmal als „Metaklassenverwirrung“
bezeichnet und lässt sich vermeiden, indem man bei der Suche nach
speziellen Methoden die Instanz umgeht:

   >>> type(1).__hash__(1) == hash(1)
   True
   >>> type(int).__hash__(int) == hash(int)
   True

Abgesehen davon, dass aus Gründen der Korrektheit alle
Instanzattribute umgangen werden, umgeht die implizite Suche nach
speziellen Methoden im Allgemeinen auch die Methode `
"__getattribute__()" *, selbst wenn es sich bei der Metaklasse des
Objekts um `metaclass:* handelt:

   >>> class Meta(type):
   ...     def __getattribute__(*args):
   ...         print("Metaklasse getattribute aufgerufen")
   ...         return type.__getattribute__(*args)
   ...
   >>> class C(object, metaclass=Meta):
   ...     def __len__(self):
   ...         return 10
   ...     def __getattribute__(*args):
   ...         print("Klassen-getattribute aufgerufen")
   ...         return object.__getattribute__(*args)
   ...
   >>> c = C()
   >>> c.__len__()                 # Explizite Suche über die Instanz
   Class getattribute invoked
   10
   >>> type(c).__len__(c)          # Explizite Abfrage über den Typ
   Metaklassen-getattribute aufgerufen
   10
   >>> len(c)                      # Implizite Abfrage
   10

Die Umgehung der „ "__getattribute__()" “-Mechanismen auf diese Weise
bietet erheblichen Spielraum für Geschwindigkeitsoptimierungen
innerhalb des Interpreters, geht jedoch zu Lasten einer gewissen
Flexibilität bei der Handhabung spezieller Methoden (die spezielle
Methode *muss* am Klassenobjekt selbst festgelegt werden, damit sie
vom Interpreter konsistent aufgerufen wird).


3.4. Coroutinen
===============


3.4.1. Objekte, auf die man warten kann
---------------------------------------

Ein *awaitable*-Objekt implementiert in der Regel eine "__await__()"
-Methode. *Coroutine-Objekte*, die von "async def"-Funktionen
zurückgegeben werden, sind awaitable.

Bemerkung:

  Die *Generator-Iterator*-Objekte, die von Generatoren zurückgegeben
  werden, die mit "types.coroutine()" dekoriert sind, sind ebenfalls
  abwartbar, implementieren jedoch nicht "__await__()".

object.__await__(self)

   Muss einen *Iterator* zurückgeben. Sollte zur Implementierung von
   *awaitable*-Objekten verwendet werden. Beispielsweise implementiert
   "asyncio.Future" diese Methode, um mit dem Ausdruck "await"
   kompatibel zu sein. Die Klasse "object" selbst ist nicht
   „awaitable“ und stellt diese Methode nicht bereit.

   Bemerkung:

     Die Sprache legt keinerlei Einschränkungen hinsichtlich des Typs
     oder des Werts der Objekte fest, die vom Iterator zurückgegeben
     werden, der von "__await__" zurückgegeben wird, da dies
     spezifisch für die Implementierung des Frameworks für die
     asynchrone Ausführung (z. B. "asyncio") ist, das das
     *awaitable*-Objekt verwaltet.

Added in version 3.5.

Siehe auch:

  **PEP 492** Weitere Informationen zu Objekten, auf die gewartet
  werden kann.


3.4.2. Coroutinen-Objekte
-------------------------

*Coroutine-Objekte* sind *awaitable*-Objekte. Die Ausführung einer
Coroutine lässt sich steuern, indem man "__await__()" aufruft und das
Ergebnis durchläuft.  Wenn die Coroutine ihre Ausführung beendet hat
und zurückkehrt, löst der Iterator eine "StopIteration" aus, und das
Attribut "value" der Ausnahme enthält den Rückgabewert.  Wenn die
Coroutine eine Ausnahme auslöst, wird diese vom Iterator
weitergeleitet.  Coroutinen sollten keine unbehandelten „
"StopIteration" “-Ausnahmen direkt auslösen.

Coroutinen verfügen außerdem über die unten aufgeführten Methoden, die
denen von Generatoren entsprechen (siehe Generator-Iterator-Methoden).
Im Gegensatz zu Generatoren unterstützen Coroutinen jedoch keine
direkte Iteration.

Coroutinen sind generische über die Typen ihrer *yield*-, *send*- bzw.
*return*-Werte.

Geändert in Version 3.5.2: Es ist ein „ "RuntimeError" “, mehr als
einmal auf eine Coroutine zu warten.

coroutine.send(value)

   Startet oder setzt die Ausführung der Coroutine fort.  Wenn *value*
   „ "None" “ ist, entspricht dies dem Weiterleiten des von „
   "__await__()" “ zurückgegebenen Iterators.  Wenn *value* nicht „
   "None" “ ist, delegiert diese Methode an die Methode „ "send()" “
   des Iterators, der die Unterbrechung der Koroutine verursacht hat.
   Das Ergebnis (Rückgabewert, „ "StopIteration" “ oder eine andere
   Ausnahme) entspricht dem oben beschriebenen Fall, in dem der
   Rückgabewert von „ "__await__()" “ durchlaufen wird.

coroutine.throw(value)
coroutine.throw(type[, value[, traceback]])

   Löst die angegebene Ausnahme in der Coroutine aus. Diese Methode
   delegiert an die Methode "throw()" des Iterators, der die
   Unterbrechung der Coroutine verursacht hat, sofern dieser über eine
   solche Methode verfügt. Andernfalls wird die Ausnahme am
   Unterbrechungspunkt ausgelöst.  Das Ergebnis (Rückgabewert,
   "StopIteration" oder eine andere Ausnahme) entspricht dem Fall, in
   dem der oben beschriebene Rückgabewert von "__await__()"
   durchlaufen wird. Wird die Ausnahme in der Koroutine nicht
   abgefangen, wird sie an den Aufrufer weitergeleitet.

   Geändert in Version 3.12: Die zweite Signatur (type[, value[,
   traceback]]) ist veraltet und wird möglicherweise in einer
   zukünftigen Version von Python entfernt.

coroutine.close()

   Bewirkt, dass die Coroutine ihre Ressourcen freigibt und beendet
   wird. Wenn die Coroutine angehalten wurde, wird diese Methode
   zunächst an die Methode ` "close()" ` des Iterators delegiert, der
   das Anhalten der Coroutine verursacht hat, sofern dieser über eine
   solche Methode verfügt. Anschließend wird am Haltepunkt ein `
   "GeneratorExit" ` ausgelöst, wodurch die Coroutine ihre Ressourcen
   sofort freigibt. Schließlich wird die Coroutine als ausgeführt
   markiert, auch wenn sie nie gestartet wurde.

   Coroutine-Objekte werden automatisch nach dem oben beschriebenen
   Verfahren geschlossen, wenn sie kurz vor der Löschung stehen.


3.4.3. Asynchrone Iteratoren
----------------------------

Ein *asynchroner Iterator* kann in seiner Methode „ "__anext__" “
asynchronen Code aufrufen.

Asynchrone Iteratoren können in einer "async for"-Anweisung verwendet
werden.

Die Klasse „ "object" “ selbst stellt diese Methoden nicht zur
Verfügung.

object.__aiter__(self)

   Muss ein *asynchrones Iterator*-Objekt zurückgeben.

object.__anext__(self)

   Muss ein *awaitable* zurückgeben, das den nächsten Wert des
   Iterators liefert. Sollte einen Fehler vom Typ „
   "StopAsyncIteration" “ auslösen, wenn die Iteration beendet ist.

Ein Beispiel für ein asynchrones iterierbares Objekt:

   Klasse Reader:
       async def readline(self):
           ...

       def __aiter__(self):
           return self

       async def __anext__(self):
           val = await self.readline()
           if val == b'':
               raise StopAsyncIteration
           return val

Added in version 3.5.

Geändert in Version 3.7: Vor Python 3.7 konnte ` "__aiter__()" ` ein
*awaitable* zurückgeben, das zu einem *asynchronen Iterator* aufgelöst
wurde.Ab Python 3.7 muss ` "__aiter__()" ` ein asynchrones Iterator-
Objekt zurückgeben. Wird etwas anderes zurückgegeben, führt dies zu
einem Fehler vom Typ „ "TypeError" “.


3.4.4. Asynchrone Kontextmanager
--------------------------------

Ein *asynchroner Kontextmanager* ist ein *Kontextmanager*, der die
Ausführung in seinen Methoden „ "__aenter__" “ und „ "__aexit__" “
unterbrechen kann.

Asynchrone Kontextmanager können in einer "async with"-Anweisung
verwendet werden.

Die Klasse „ "object" “ selbst stellt diese Methoden nicht zur
Verfügung.

object.__aenter__(self)

   Semantisch ähnlich wie „ "__enter__()" “, mit dem einzigen
   Unterschied, dass es ein *awaitable* zurückgeben muss.

object.__aexit__(self, exc_type, exc_value, traceback)

   Semantisch ähnlich wie „ "__exit__()" “, mit dem einzigen
   Unterschied, dass hier ein *awaitable* zurückgegeben werden muss.

Ein Beispiel für eine asynchrone Kontextmanager-Klasse:

   Klasse AsyncContextManager:
       async def __aenter__(self):
           await log('Kontext wird betreten')

       async def __aexit__(self, exc_type, exc, tb):
           await log('Kontext wird verlassen')

Added in version 3.5.

-[ Fußnoten ]-

[1] In manchen Fällen *ist* es unter bestimmten kontrollierten
    Bedingungen möglich, den Typ eines Objekts zu ändern. Im
    Allgemeinen ist dies jedoch keine gute Idee, da es bei
    unsachgemäßer Handhabung zu sehr seltsamen Verhaltensweisen führen
    kann.

[2] Die Methoden „ "__hash__()" “, „ "__iter__()" “, „
    "__reversed__()" “, „ "__contains__()" “, „ "__class_getitem__()"
    “ und „ "__fspath__()" “ verfügen hierfür über eine spezielle
    Behandlung. Andere Methoden lösen weiterhin einen „ "TypeError" “
    aus, stützen sich dabei jedoch möglicherweise auf das Verhalten,
    dass „ "None" “ nicht aufrufbar ist.

[3] „Unterstützt nicht“ bedeutet hier, dass die Klasse keine solche
    Methode besitzt oder die Methode "NotImplemented" zurückgibt.
    Setze die Methode nicht auf "None", wenn du den Rückgriff auf die
    gespiegelte Methode des rechten Operanden erzwingen willst – das
    bewirkt genau das Gegenteil und *verhindert* diesen Rückgriff
    ausdrücklich.

[4] For operands of the same type, it is assumed that if the non-
    reflected method -- such as "__add__()" -- fails then the overall
    operation is not supported, which is why the reflected method is
    not called.
