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


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

*Objects* are Python's abstraction for data.  All data in a Python
program is represented by objects or by relations between objects. (In
a sense, and in conformance to Von Neumann's model of a "stored
program computer", code is also represented by objects.)

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.

**CPython-Implementierungsdetail:** 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-Implementierungsdetail:** 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.

Types affect almost all aspects of object behavior.  Even the
importance of object identity is affected in some sense: for immutable
types, operations that compute new values may actually return a
reference to any existing object with the same type and value, while
for mutable objects this is not allowed.  E.g., after "a = 1; b = 1",
"a" and "b" may or may not refer to the same object with the value
one, depending on the implementation, but after "c = []; d = []", "c"
and "d" are guaranteed to refer to two different, unique, newly
created empty lists. (Note that "c = d = []" assigns the same object
to both "c" and "d".)


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 distinguishes between integers, floating point numbers, and
complex numbers:


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")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

These represent machine-level double precision floating point numbers.
You are at the mercy of the underlying machine architecture (and C or
Java implementation) for the accepted range and handling of overflow.
Python does not support single-precision floating point numbers; the
savings in processor and memory usage that are usually the reason for
using these are dwarfed by the overhead of using objects in Python, so
there is no reason to complicate the language with two kinds of
floating point numbers.


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

These represent complex numbers as a pair of machine-level double
precision floating point numbers.  The same caveats apply as for
floating point numbers. The real and imaginary parts of a complex
number "z" can be retrieved through the read-only attributes "z.real"
and "z.imag".


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.

Dictionaries are mutable; they can be created by the "{...}" notation
(see section 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.__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" or a "tuple" of cells that contain bindings |
|                                                    | for the function's free variables.  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__                                   | The function's documentation string, or "None" if  |
|                                                    | unavailable. Not inherited by subclasses.          |
+----------------------------------------------------+----------------------------------------------------+
| function.__name__                                  | Der Name der Funktion. Siehe auch:                 |
|                                                    | "__name__-Attribute".                              |
+----------------------------------------------------+----------------------------------------------------+
| function.__qualname__                              | Der *qualifizierte Name* der Funktion. Siehe auch: |
|                                                    | "__qualname__-Attribute".  Neu 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*.                                    |
+----------------------------------------------------+----------------------------------------------------+

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.

**CPython-Implementierungsdetail:** 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.

Note that the transformation from function object to instance method
object happens each time the attribute is retrieved from the instance.
In some cases, a fruitful optimization is to assign the attribute to a
local variable and call that local variable. Also notice that this
transformation only happens for user-defined functions; other callable
objects (and all non-callable objects) are retrieved without
transformation.  It is also important to note that user-defined
functions which are attributes of a class instance are not converted
to bound methods; this *only* happens when the function is an
attribute of the class.


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

A function or method which uses the "yield" statement (see section Die
yield Anweisung) 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" statement.  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 uses
the "yield" statement 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`".

Predefined (writable) attributes:

   "__name__"
      The module's name.

   "__doc__"
      The module's documentation string, or "None" if unavailable.

   "__file__"
      The pathname of the file from which the module was loaded, if it
      was loaded from a file. The "__file__" attribute may be missing
      for certain types of modules, such as C modules that are
      statically linked into the interpreter.  For extension modules
      loaded dynamically from a shared library, it's the pathname of
      the shared library file.

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

Special read-only attribute: "__dict__" is the module's namespace as a
dictionary object.

**CPython-Implementierungsdetail:** 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
----------------------------------

Custom class types are typically created by class definitions (see
section Klassendefinitionen).  A class has a namespace implemented by
a dictionary object. Class attribute references are translated to
lookups in this dictionary, e.g., "C.x" is translated to
"C.__dict__["x"]" (although there are a number of hooks which allow
for other means of locating attributes). When the attribute name is
not found there, the attribute search continues in the base classes.
This search of the base classes uses the C3 method resolution order
which behaves correctly even in the presence of 'diamond' inheritance
structures where there are multiple inheritance paths leading back to
a common ancestor. Additional details on the C3 MRO used by Python can
be found in the documentation accompanying the 2.3 release at
https://www.python.org/download/releases/2.3/mro/.

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).

Special attributes:

   "__name__"
      The class name.

   "__module__"
      Der Name des Moduls, in dem die Klasse definiert wurde.

   "__dict__"
      The dictionary containing the class's namespace.

   "__bases__"
      A tuple containing the base classes, in the order of their
      occurrence in the base class list.

   "__doc__"
      The class's documentation string, or "None" if undefined.

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


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 “.

Special attributes: "__dict__" is the attribute dictionary;
"__class__" is the instance's class.


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).

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.


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  Neu 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                             | A "tuple" containing the names of local variables  |
|                                                    | that are referenced by nested functions inside the |
|                                                    | function                                           |
+----------------------------------------------------+----------------------------------------------------+
| codeobject.co_freevars                             | A "tuple" containing the names of free variables   |
|                                                    | in the function                                    |
+----------------------------------------------------+----------------------------------------------------+
| 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.                                      |
+----------------------------------------------------+----------------------------------------------------+
| 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.

Future feature declarations ("from __future__ import division") also
use bits in "co_flags" to indicate whether a code object was compiled
with a particular feature enabled: bit "0x2000" is set if the function
was compiled with future division enabled; bits "0x10" and "0x1000"
were used in earlier versions of Python.

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.

   Neu 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.

   Neu 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.

   Neu 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                                     | The dictionary used by the frame to look up local  |
|                                                    | variables                                          |
+----------------------------------------------------+----------------------------------------------------+
| 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" is raised if the frame is currently executing.

   Neu in Version 3.4.


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]

When implementing a class that emulates any built-in type, it is
important that the emulation only be implemented to the degree that it
makes sense for the object being modelled.  For example, some
sequences may work well with retrieval of individual elements, but
extracting a slice may not make sense.  (One example of this is the
"NodeList" interface in the W3C's Document Object Model.)


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.

   It is not guaranteed that "__del__()" methods are called for
   objects that still exist when the interpreter exits.

   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.

   **CPython-Implementierungsdetail:** 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.

   This is typically used for debugging, so it is important that the
   representation is information-rich and unambiguous.

object.__str__(self)

   Called by "str(object)" and the built-in functions "format()" and
   "print()" to compute the "informal" or nicely printable string
   representation of an object.  The return value must be a string
   object.

   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)

   Called by bytes to compute a byte-string representation of an
   object. This should return a "bytes" object.

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
   Format Specification Mini-Language.

   Der Rückgabewert muss ein String-Objekt sein.

   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.

   By default, "object" implements "__eq__()" by using "is", returning
   "NotImplemented" in the case of a false comparison: "True if x is y
   else NotImplemented". For "__ne__()", by default it delegates to
   "__eq__()" and inverts the result unless it is "NotImplemented".
   There are no other implied relationships among the comparison
   operators or default implementations; for example, the truth of
   "(x<y or x==y)" does not imply "x<=y". To automatically generate
   ordering operations from a single root operation, see
   "functools.total_ordering()".

   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.

   User-defined classes have "__eq__()" and "__hash__()" methods by
   default; with them, all objects compare unequal (except with
   themselves) and "x.__hash__()" returns an appropriate value such
   that "x == y" implies both that "x is y" and "hash(x) == hash(y)".

   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.This is intended to provide protection against
     a denial-of-service caused by carefully chosen inputs that
     exploit the worst case performance of a dict insertion,
     *O*(*n*^2) complexity.  See
     http://ocert.org/advisories/ocert-2011-003.html for details.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)

   Called to implement truth value testing and the built-in operation
   "bool()"; should return "False" or "True".  When this method is not
   defined, "__len__()" is called, if it is defined, and the object is
   considered true if its result is nonzero.  If a class defines
   neither "__len__()" nor "__bool__()", all its instances are
   considered true.


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)

   Called when the default attribute access fails with an
   "AttributeError" (either "__getattribute__()" raises an
   "AttributeError" because *name* is not an instance attribute or an
   attribute in the class tree for "self"; or "__get__()" of a *name*
   property raises "AttributeError").  This method should either
   return the (computed) attribute value or raise an "AttributeError"
   exception.

   Note that if the attribute is found through the normal mechanism,
   "__getattr__()" is not called.  (This is an intentional asymmetry
   between "__getattr__()" and "__setattr__()".) This is done both for
   efficiency reasons and because otherwise "__getattr__()" would have
   no way to access other attributes of the instance.  Note that at
   least for instance variables, you can fake total control by not
   inserting any values in the instance attribute dictionary (but
   instead inserting them in another object).  See the
   "__getattribute__()" method below for a way to actually get total
   control over attribute access.

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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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()".

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'Setting {attr}...')
           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.

Neu 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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The following methods only apply when an instance of the class
containing the method (a so-called *descriptor* class) appears in an
*owner* class (the descriptor must be in either the owner's class
dictionary or in the class dictionary for one of its parents).  In the
examples below, "the attribute" refers to the attribute whose name is
the key of the property in the owner class' "__dict__".

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 methods (including those decorated with "@staticmethod" and
"@classmethod") are implemented as non-data descriptors.  Accordingly,
instances can redefine and override methods.  This allows individual
instances to acquire behaviors that differ from other instances of the
same class.

The "property()" function is implemented as a data descriptor.
Accordingly, instances cannot override the behavior of a property.


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.

* The action of a *__slots__* declaration is not limited to the class
  where it is defined.  *__slots__* declared in parents are available
  in child classes. However, child subclasses will get a "__dict__"
  and *__weakref__* unless they also define *__slots__* (which should
  only contain names of any *additional* slots).

* 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__" assignment works only if both classes have the same
  *__slots__*.

* 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:

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

      class 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.

   Neu in Version 3.6.

When a class is created, "type.__new__()" scans the class variables
and makes callbacks to those with a "__set_name__()" hook.

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:

      class A:
          x = C()  # Automatically calls: 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:

      class A:
         pass

      c = C()
      A.x = c                  # The hook is not called
      c.__set_name__(A, 'x')   # Manually invoke the hook

   Weitere Informationen findest du unter Erstellen des
   Klassenobjekts.

   Neu 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.

  **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.

**CPython-Implementierungsdetail:** 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.

When a new class is created by "type.__new__", the object provided as
the namespace parameter is copied to a new ordered mapping and the
original object is discarded. The new copy is wrapped in a read-only
proxy, which becomes the "__dict__" attribute of the class object.

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.

class.__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.

class.__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
     Includes the specification for customizing "isinstance()" and
     "issubclass()" behavior through "__instancecheck__()" and
     "__subclasscheck__()", with motivation for this functionality in
     the context of adding Abstract Base Classes (see the "abc"
     module) to the language.


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.

   When defined on a class, "__class_getitem__()" is automatically a
   class method. As such, there is no need for it to be decorated with
   "@classmethod" when it is defined.


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):
       """Return the result of the expression 'obj[x]'"""

       class_of_obj = type(obj)

       # If the class of obj defines __getitem__,
       # call class_of_obj.__getitem__(obj, x)
       if hasattr(class_of_obj, '__getitem__'):
           return class_of_obj.__getitem__(obj, x)

       # Else, if obj is a class and defines __class_getitem__,
       # call obj.__class_getitem__(x)
       elif isclass(obj) and hasattr(obj, '__class_getitem__'):
           return obj.__class_getitem__(x)

       # Else, raise an exception
       else:
           raise TypeError(
               f"'{class_of_obj.__name__}' object is not subscriptable"
           )

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 has class "type" as its metaclass, like most classes:
   >>> 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):
   ...     """A breakfast menu"""
   ...     SPAM = 'spam'
   ...     BACON = 'bacon'
   ...
   >>> # Enum classes have a custom metaclass:
   >>> type(Menu)
   <class 'enum.EnumMeta'>
   >>> # EnumMeta defines __getitem__,
   >>> # so __class_getitem__ is not called,
   >>> # and the result is not a GenericAlias object:
   >>> 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...])

   Called when the instance is "called" as a function; if this method
   is defined, "x(arg1, arg2, ...)" roughly translates to
   "type(x).__call__(x, arg1, ...)".


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

The following methods can be defined to implement container objects.
Containers usually are *sequences* (such as "lists" or "tuples") or
*mappings* (like "dictionaries"), but can represent other containers
as well.  The first set of methods is used either to emulate a
sequence or to emulate a mapping; the difference is that for a
sequence, the allowable keys should be the integers *k* for which "0
<= k < N" where *N* is the length of the sequence, or "slice" objects,
which define a range of items.  It is also recommended that mappings
provide the methods "keys()", "values()", "items()", "get()",
"clear()", "setdefault()", "pop()", "popitem()", "copy()", and
"update()" behaving similar to those for Python's standard
"dictionary" objects.  The "collections.abc" module provides a
"MutableMapping" *abstract base class* to help create those methods
from a base set of "__getitem__()", "__setitem__()", "__delitem__()",
and "keys()". Mutable sequences should provide methods "append()",
"count()", "index()", "extend()", "insert()", "pop()", "remove()",
"reverse()" and "sort()", like Python standard "list" objects.
Finally, sequence types should implement addition (meaning
concatenation) and multiplication (meaning repetition) by defining the
methods "__add__()", "__radd__()", "__iadd__()", "__mul__()",
"__rmul__()" and "__imul__()" described below; they should not define
other numerical operators.  It is recommended that both mappings and
sequences implement the "__contains__()" method to allow efficient use
of the "in" operator; for mappings, "in" should search the mapping's
keys; for sequences, it should search through the values.  It is
further recommended that both mappings and sequences implement the
"__iter__()" method to allow efficient iteration through the
container; for mappings, "__iter__()" should iterate through the
object's keys; for sequences, it should iterate through the values.

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.

   **CPython-Implementierungsdetail:** 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.

   Neu 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.

For more information on context managers, see Context Manager Types.

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.

Neu in Version 3.10.

Siehe auch:

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


3.3.11. 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 (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: object of type 'C' has no len()

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 (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: descriptor '__hash__' of 'int' object needs an 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("Metaclass getattribute invoked")
   ...         return type.__getattribute__(*args)
   ...
   >>> class C(object, metaclass=Meta):
   ...     def __len__(self):
   ...         return 10
   ...     def __getattribute__(*args):
   ...         print("Class getattribute invoked")
   ...         return object.__getattribute__(*args)
   ...
   >>> c = C()
   >>> c.__len__()                 # Explicit lookup via instance
   Class getattribute invoked
   10
   >>> type(c).__len__(c)          # Explicit lookup via type
   Metaclass getattribute invoked
   10
   >>> len(c)                      # Implicit lookup
   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)

   Must return an *iterator*.  Should be used to implement *awaitable*
   objects.  For instance, "asyncio.Future" implements this method to
   be compatible with the "await" expression.

   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.

Neu 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.

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.

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.

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:

   class 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

Neu 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.

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:

   class AsyncContextManager:
       async def __aenter__(self):
           await log('entering context')

       async def __aexit__(self, exc_type, exc, tb):
           await log('exiting context')

Neu 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] The "__hash__()", "__iter__()", "__reversed__()", and
    "__contains__()" methods have special handling for this; others
    will still raise a "TypeError", but may do so by relying on the
    behavior that "None" is not callable.

[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.
