3. Datenmodell

3.1. Objekte, Werte und Typen

Objekte sind Pythons Abstraktion für Daten. Alle Daten in einem Python-Programm werden durch Objekte oder Beziehungen zwischen Objekten dargestellt. (In gewissem Sinne und in Übereinstimmung mit Von Neumanns Modell eines „Programmspeichers“ werden auch Codes durch Objekte repräsentiert.)

Jedes Objekt hat eine Identität, einen Typ und einen Wert. Die Identität eines Objekts ändert sich nie, nachdem es erstellt wurde; man kann sich sie 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 seine Identität darstellt.

CPython Implementierungsdetail: Für CPython ist id(x) die Speicheradresse, an der x gespeichert ist.

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

Der Wert einiger Objekte kann sich ändern. Objekte, deren Wert sich ändern kann, werden als veränderlich bezeichnet; Objekte, deren Wert nach ihrer Erstellung unveränderlich ist, werden als unveränderlich bezeichnet. (Der Wert eines unveränderlichen Containerobjekts, das eine Referenz auf ein veränderliches Objekt enthält, kann sich ändern, wenn der Wert des letzteren geändert wird; das Containerobjekt wird jedoch immer noch als unveränderlich betrachtet, da die Sammlung der von ihm enthaltenen Objekte nicht geändert werden kann. Unveränderlichkeit ist also nicht streng dasselbe wie ein unveränderlicher Wert, es ist subtiler.) Die Veränderlichkeit eines Objekts wird durch seinen Typ bestimmt; zum Beispiel sind Zahlen, Zeichenketten und Tupel unveränderlich, während Dictionaries und Listen veränderlich sind.

Objekte werden niemals explizit zerstört; wenn sie jedoch unerreichbar werden, können sie vom Garbage Collector gesammelt werden. Eine Implementierung ist berechtigt, die Garbage Collection zu verzögern oder ganz wegzulassen – es ist eine Frage der Implementierungsqualität, wie die Garbage Collection implementiert wird, solange keine Objekte gesammelt werden, die noch erreichbar sind.

CPython Implementierungsdetail: CPython verwendet derzeit ein Referenzzählungsschema mit (optionaler) verzögerter Erkennung von zyklisch verknüpftem Müll, das die meisten Objekte sammelt, sobald sie unerreichbar werden, aber nicht garantiert Müll mit zyklischen Referenzen sammelt. Informationen zur Steuerung der Sammlung von zyklischem Müll finden Sie in der Dokumentation des Moduls gc. Andere Implementierungen verhalten sich anders und CPython kann sich ändern. Verlassen Sie sich nicht auf die sofortige Finalisierung von Objekten, wenn sie unerreichbar werden (daher sollten Sie Dateien immer explizit schließen).

Beachten Sie, dass die Verwendung der Tracing- oder Debugging-Einrichtungen der Implementierung Objekte am Leben erhalten kann, die normalerweise sammelbar wären. Beachten Sie auch, dass das Abfangen einer Ausnahme mit einer tryexcept-Anweisung Objekte am Leben erhalten kann.

Einige Objekte enthalten Referenzen auf „externe“ Ressourcen wie offene Dateien oder Fenster. Es versteht sich, dass diese Ressourcen freigegeben werden, wenn das Objekt vom Garbage Collector gesammelt wird, aber da die Garbage Collection nicht garantiert stattfindet, bieten solche Objekte auch eine explizite Möglichkeit, die externe Ressource freizugeben, normalerweise eine close()-Methode. Es wird dringend empfohlen, solche Objekte explizit zu schließen. Die tryfinally-Anweisung und die with-Anweisung bieten bequeme Möglichkeiten, dies zu tun.

Einige Objekte enthalten Referenzen auf andere Objekte; diese werden als Container bezeichnet. Beispiele für Container sind Tupel, Listen und Dictionaries. Die Referenzen sind Teil des Werts eines Containers. In den meisten Fällen implizieren wir, wenn wir über den Wert eines Containers sprechen, die Werte, nicht die Identitäten der enthaltenen Objekte; wenn wir jedoch über die Veränderlichkeit eines Containers sprechen, werden nur die Identitäten der unmittelbar enthaltenen Objekte impliziert. Wenn also ein unveränderlicher Container (wie ein Tupel) eine Referenz auf ein veränderliches Objekt enthält, ändert sich sein Wert, wenn das letztere geändert wird.

Typen beeinflussen fast alle Aspekte des Objektverhaltens. Sogar die Bedeutung der Objektidentität wird in gewissem Sinne beeinflusst: für unveränderliche Typen können Operationen, die neue Werte berechnen, tatsächlich eine Referenz auf ein beliebiges vorhandenes Objekt mit demselben Typ und Wert zurückgeben, während dies bei veränderlichen Objekten nicht erlaubt ist. Zum Beispiel, nach a = 1; b = 1 können a und b je nach Implementierung auf dasselbe Objekt mit dem Wert eins verweisen oder nicht. Dies liegt daran, dass int ein unveränderlicher Typ ist, sodass die Referenz auf 1 wiederverwendet werden kann. Dieses Verhalten hängt von der verwendeten Implementierung ab und sollte daher nicht als zuverlässig betrachtet werden, aber es ist etwas, das bei der Verwendung von Objektidentitätstests zu beachten ist. Nach c = []; d = [] wird jedoch garantiert, dass c und d auf zwei verschiedene, eindeutige, neu erstellte leere Listen verweisen. (Beachten Sie, dass e = f = [] dasselbe Objekt an e und f zuweist.)

3.2. Die Standard-Typenhierarchie

Nachfolgend finden Sie eine Liste der in Python eingebauten Typen. Erweiterungsmodule (in C, Java oder anderen Sprachen geschrieben, je nach Implementierung) können zusätzliche Typen definieren. Zukünftige Versionen von Python können Typen zur Typenhierarchie hinzufügen (z. B. rationale Zahlen, effizient gespeicherte Arrays von Ganzzahlen usw.), obwohl solche Ergänzungen oft stattdessen über die Standardbibliothek bereitgestellt werden.

Einige der folgenden Typbeschreibungen enthalten einen Absatz mit einer Liste von „speziellen Attributen“. Dies sind Attribute, die Zugriff auf die Implementierung ermöglichen und nicht für den allgemeinen Gebrauch bestimmt sind. Ihre Definition kann sich in Zukunft ändern.

3.2.1. None

Dieser Typ hat einen einzigen Wert. Es gibt ein einzelnes Objekt mit diesem Wert. Dieses Objekt wird über den eingebauten Namen None aufgerufen. Es wird verwendet, um in vielen Situationen das Fehlen eines Wertes anzuzeigen, z. B. wird es von Funktionen zurückgegeben, die nichts explizit zurückgeben. Sein Wahrheitswert ist falsch.

3.2.2. NotImplemented

Dieser Typ hat einen einzigen Wert. Es gibt ein einzelnes Objekt mit diesem Wert. Dieses Objekt wird über den eingebauten Namen NotImplemented aufgerufen. Numerische Methoden und Rich-Comparison-Methoden sollten diesen Wert zurückgeben, wenn sie die Operation für die bereitgestellten Operanden nicht implementieren. (Der Interpreter wird dann die reflektierte Operation oder einen anderen Fallback versuchen, abhängig vom Operator.) Er sollte nicht in einem booleschen Kontext ausgewertet werden.

Weitere Details finden Sie unter Implementierung der arithmetischen Operationen.

Geändert in Version 3.9: Das Auswerten von NotImplemented in einem booleschen Kontext wurde als veraltet markiert.

Geändert in Version 3.14: Das Auswerten von NotImplemented in einem booleschen Kontext löst nun einen TypeError aus. Zuvor wurde er als True ausgewertet und gab seit Python 3.9 eine DeprecationWarning aus.

3.2.3. Ellipsis

Dieser Typ hat einen einzigen Wert. Es gibt ein einzelnes Objekt mit diesem Wert. Dieses Objekt wird über das Literal ... oder den eingebauten Namen Ellipsis aufgerufen. Sein Wahrheitswert ist wahr.

3.2.4. numbers.Number

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

Die String-Darstellungen der numerischen Klassen, berechnet durch __repr__() und __str__(), haben die folgenden Eigenschaften

  • Sie sind gültige numerische Literale, die, wenn sie an ihren Klassenkonstruktor übergeben werden, ein Objekt mit dem Wert der ursprünglichen Zahl erzeugen.

  • Die Darstellung erfolgt nach Möglichkeit in Basis 10.

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

  • Nachfolgende Nullen, möglicherweise mit Ausnahme einer einzelnen Null nach einem Dezimalpunkt, werden nicht angezeigt.

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

Python unterscheidet zwischen ganzen Zahlen, Gleitkommazahlen und komplexen Zahlen.

3.2.4.1. numbers.Integral

Diese repräsentieren Elemente aus der mathematischen Menge der ganzen Zahlen (positiv und negativ).

Hinweis

Die Regeln für die Ganzzahldarstellung sind so gedacht, dass sie die aussagekräftigste Interpretation von Shift- und Maskierungsoperationen mit negativen Ganzzahlen ermöglichen.

Es gibt zwei Arten von ganzen Zahlen

Ganzzahlen (int)

Diese repräsentieren Zahlen in einem unbegrenzten Bereich, der nur durch den verfügbaren (virtuellen) Speicher begrenzt ist. Für Shift- und Maskierungsoperationen wird eine binäre Darstellung angenommen, und negative Zahlen werden in einer Variante von 2er-Komplement dargestellt, die die Illusion einer unendlichen Zeichenkette von Vorzeichenbits nach links erzeugt.

Booleans (bool)

Diese repräsentieren die Wahrheitswerte False und True. Die beiden Objekte, die die Werte False und True repräsentieren, sind die einzigen booleschen Objekte. Der boolesche Typ ist ein Untertyp des Ganzzahltyps, und boolesche Werte verhalten sich in fast allen Kontexten wie die Werte 0 und 1, mit der Ausnahme, dass bei der Konvertierung in eine Zeichenkette die Zeichenketten "False" bzw. "True" zurückgegeben werden.

3.2.4.2. numbers.Real (float)

Diese repräsentieren Maschinen-Gleitkommazahlen mit doppelter Genauigkeit. Sie sind den Einschränkungen der zugrundeliegenden Maschinenarchitektur (und der C- oder Java-Implementierung) hinsichtlich des akzeptierten Bereichs und der Handhabung von Überläufen unterworfen. Python unterstützt keine Gleitkommazahlen mit einfacher Genauigkeit; die Einsparungen bei Prozessor- und Speicherverbrauch, die normalerweise der Grund für die Verwendung dieser sind, werden durch den Overhead der Verwendung von Objekten in Python überschattet, sodass es keinen Grund gibt, die Sprache mit zwei Arten von Gleitkommazahlen zu komplizieren.

3.2.4.3. numbers.Complex (complex)

Diese repräsentieren komplexe Zahlen als Paar von Maschinen-Gleitkommazahlen mit doppelter Genauigkeit. Die gleichen Vorbehalte gelten wie für Gleitkommazahlen. Der Real- und Imaginärteil einer komplexen Zahl z können über die schreibgeschützten Attribute z.real und z.imag abgerufen werden.

3.2.5. Sequenzen

Diese repräsentieren endliche geordnete Mengen, die durch nicht-negative Zahlen indiziert werden. Die eingebaute Funktion len() gibt die Anzahl der Elemente einer Sequenz zurück. Wenn die Länge einer Sequenz n ist, enthält die Indexmenge die Zahlen 0, 1, …, n-1. Das Element i der Sequenz a wird durch a[i] ausgewählt. Einige Sequenzen, einschließlich integrierter Sequenzen, interpretieren negative Indizes, indem sie die Sequenzlänge addieren. Zum Beispiel ist a[-2] gleich a[n-2], das vorletzte Element der Sequenz a mit der Länge n.

Sequenzen unterstützen auch das Slicing: a[i:j] wählt alle Elemente mit Index k aus, für die i <= k < j gilt. Wenn ein Slice als Ausdruck verwendet wird, ist er eine Sequenz desselben Typs. Der Kommentar oben zu negativen Indizes gilt auch für negative Slice-Positionen.

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

Sequenzen werden nach ihrer Veränderlichkeit unterschieden.

3.2.5.1. Unveränderliche Sequenzen

Ein Objekt eines unveränderlichen Sequenztyps kann nach seiner Erstellung nicht geändert werden. (Wenn das Objekt Referenzen auf andere Objekte enthält, können diese anderen Objekte veränderlich sein und geändert werden; die Sammlung von Objekten, auf die ein unveränderliches Objekt direkt verweist, kann jedoch nicht geändert werden.)

Die folgenden Typen sind unveränderliche Sequenzen

Zeichenketten

Eine Zeichenkette ist eine Sequenz von Werten, die Unicode-Codepunkte darstellen. Alle Codepunkte im Bereich U+0000 - U+10FFFF können in einer Zeichenkette dargestellt werden. Python hat keinen char-Typ; stattdessen wird jeder Codepunkt in der Zeichenkette als Zeichenkettenobjekt der Länge 1 dargestellt. Die eingebaute Funktion ord() konvertiert einen Codepunkt von seiner Zeichenkettenform in eine Ganzzahl im Bereich 0 - 10FFFF; chr() konvertiert eine Ganzzahl im Bereich 0 - 10FFFF in das entsprechende Zeichenkettenobjekt der Länge 1. str.encode() kann verwendet werden, um eine str mit der angegebenen Textkodierung in bytes zu konvertieren, und bytes.decode() kann verwendet werden, um das Gegenteil zu erreichen.

Tupel

Die Elemente eines Tupels sind beliebige Python-Objekte. Tupel aus zwei oder mehr Elementen werden durch kommagetrennte Ausdrücke gebildet. Ein Tupel aus einem Element (ein „Singleton“) kann durch Anhängen eines Kommas an einen Ausdruck gebildet werden (ein Ausdruck allein erzeugt kein Tupel, da Klammern für die Gruppierung von Ausdrücken verwendbar sein müssen). Ein leeres Tupel kann durch ein leeres Klammernpaar gebildet werden.

Bytes

Ein Bytes-Objekt ist ein unveränderliches Array. Die Elemente sind 8-Bit-Bytes, dargestellt durch Ganzzahlen im Bereich 0 <= x < 256. Bytes-Literale (wie b'abc') und der eingebaute bytes()-Konstruktor können verwendet werden, um Bytes-Objekte zu erstellen. Ebenso können Bytes-Objekte über die Methode decode() in Zeichenketten dekodiert werden.

3.2.5.2. Veränderliche Sequenzen

Veränderliche Sequenzen können nach ihrer Erstellung geändert werden. Die Index- und Slicing-Schreibweisen können als Ziel von Zuweisungs- und del (Löschungs-)Anweisungen verwendet werden.

Hinweis

Die Module collections und array bieten zusätzliche Beispiele für veränderliche Sequenztypen.

Es gibt derzeit zwei integrierte veränderliche Sequenztypen

Listen

Die Elemente einer Liste sind beliebige Python-Objekte. Listen werden durch Platzieren einer kommagetrennten Liste von Ausdrücken in eckigen Klammern gebildet. (Beachten Sie, dass keine Sonderfälle erforderlich sind, um Listen der Länge 0 oder 1 zu bilden.)

Byte-Arrays

Ein Bytearray-Objekt ist ein veränderliches Array. Sie werden durch den eingebauten Konstruktor bytearray() erstellt. Abgesehen davon, dass sie veränderlich (und daher nicht haschbar) sind, bieten Byte-Arrays ansonsten die gleiche Schnittstelle und Funktionalität wie unveränderliche bytes-Objekte.

3.2.6. Set-Typen

Diese repräsentieren ungeordnete, endliche Mengen eindeutiger, unveränderlicher Objekte. Als solche können sie durch keinen Index angesprochen werden. Sie können jedoch iteriert werden, und die eingebaute Funktion len() gibt die Anzahl der Elemente in einem Set zurück. Häufige Verwendungen für Sets sind schnelles Testen der Mitgliedschaft, Entfernen von Duplikaten aus einer Sequenz und Ausführen mathematischer Operationen wie Schnittmenge, Vereinigung, Differenz und symmetrische Differenz.

Für Set-Elemente gelten die gleichen Unveränderlichkeitsregeln wie für Dictionary-Schlüssel. Beachten Sie, dass numerische Typen den normalen Regeln für numerische Vergleiche folgen: Wenn zwei Zahlen gleich sind (z. B. 1 und 1.0), kann nur eine davon in einem Set enthalten sein.

Es gibt derzeit zwei integrierte Set-Typen

Sets

Diese repräsentieren ein veränderliches Set. Sie werden durch den eingebauten Konstruktor set() erstellt und können anschließend durch mehrere Methoden geändert werden, wie z. B. add.

Frozen Sets

Diese repräsentieren ein unveränderliches Set. Sie werden durch den eingebauten Konstruktor frozenset() erstellt. Da ein Frozenset unveränderlich und hashbar ist, kann es erneut als Element eines anderen Sets oder als Dictionary-Schlüssel verwendet werden.

3.2.7. Mappings

Diese repräsentieren endliche Mengen von Objekten, die von beliebigen Indexmengen indiziert werden. Die Indexnotation a[k] wählt das durch k indizierte Element aus der Abbildung a aus; dies kann in Ausdrücken und als Ziel von Zuweisungen oder del-Anweisungen verwendet werden. Die eingebaute Funktion len() gibt die Anzahl der Elemente in einer Abbildung zurück.

Derzeit gibt es einen einzigen intrinsischen Abbildungstyp

3.2.7.1. Dictionaries

Diese stellen endliche Mengen von Objekten dar, die von nahezu beliebigen Werten indiziert werden. Die einzigen Wertetypen, die nicht als Schlüssel akzeptiert werden, sind Werte, die Listen oder Wörterbücher oder andere veränderliche Typen enthalten, die nach Wert und nicht nach 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. Numerische Typen, die für Schlüssel verwendet werden, folgen den normalen Regeln für den numerischen Vergleich: Wenn zwei Zahlen gleich verglichen werden (z. B. 1 und 1.0), dann können sie austauschbar verwendet werden, um denselben Wörterbucheintrag zu indizieren.

Wörterbücher behalten die Einfügungsreihenfolge bei, was bedeutet, dass Schlüssel in der gleichen Reihenfolge ausgegeben werden, in der sie sequenziell in das Wörterbuch eingefügt wurden. Das Ersetzen eines vorhandenen Schlüssels ändert die Reihenfolge nicht. Das Entfernen eines Schlüssels und das erneute Einfügen fügt ihn jedoch am Ende hinzu, anstatt seinen alten Platz beizubehalten.

Wörterbücher sind veränderlich; sie können durch die Notation {} erstellt werden (siehe Abschnitt Dictionary-Anzeigen).

Die Erweiterungsmodule dbm.ndbm und dbm.gnu bieten zusätzliche Beispiele für Abbildungstypen, ebenso wie das Modul collections.

Geändert in Version 3.7: Wörterbücher behielten in Python-Versionen vor 3.6 die Einfügungsreihenfolge nicht bei. In CPython 3.6 wurde die Einfügungsreihenfolge beibehalten, aber sie galt damals als Implementierungsdetail und nicht als Sprachgarantie.

3.2.8. Aufrufbare Typen

Dies sind die Typen, auf die die Funktionsaufrufoperation (siehe Abschnitt Aufrufe) angewendet werden kann.

3.2.8.1. Benutzerdefinierte Funktionen

Ein benutzerdefiniertes Funktionsobjekt wird durch eine Funktionsdefinition erstellt (siehe Abschnitt Funktionsdefinitionen). Sie sollte mit einer Argumentliste aufgerufen werden, die die gleiche Anzahl von Elementen enthält wie die Liste der formalen Parameter der Funktion.

3.2.8.1.1. Spezielle schreibgeschützte Attribute

Attribut

Bedeutung

function.__globals__

Eine Referenz auf das Dictionary, das die globalen Variablen der Funktion enthält – der globale Namensraum des Moduls, in dem die Funktion definiert wurde.

function.__closure__

None oder ein Tupel von Zellen, die Bindungen für die Namen enthalten, die im Attribut co_freevars des Code-Objekts der Funktion angegeben sind.

Ein Zellobjekt hat das Attribut cell_contents. Dies kann verwendet werden, um den Wert der Zelle abzurufen und auch zu setzen.

3.2.8.1.2. Spezielle beschreibbare Attribute

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

Attribut

Bedeutung

function.__doc__

Der Dokumentationsstring der Funktion oder None, falls nicht verfügbar.

function.__name__

Der Name der Funktion. Siehe auch: __name__ Attribute.

function.__qualname__

Der qualifizierte Name der Funktion. Siehe auch: __qualname__ Attribute.

Hinzugefügt in Version 3.3.

function.__module__

Der Name des Moduls, in dem die Funktion definiert wurde, oder None, falls nicht verfügbar.

function.__defaults__

Ein Tupel mit Standardparametern für diejenigen Parameter, die Standardwerte haben, oder None, wenn keine Parameter einen Standardwert haben.

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__

Ein Dictionary, das Annotationen von Parametern enthält. Die Schlüssel des Wörterbuchs sind die Parameternamen, und 'return' für die Rückgabeannotation, falls vorhanden. Siehe auch: object.__annotations__.

Geändert in Version 3.14: Annotationen werden jetzt lazy ausgewertet. Siehe PEP 649.

function.__annotate__

Die Annotierungsfunktion für diese Funktion oder None, wenn die Funktion keine Annotationen hat. Siehe object.__annotate__.

Hinzugefügt in Version 3.14.

function.__kwdefaults__

Ein Dictionary mit Standardwerten für schlüsselwort-only Parameter.

function.__type_params__

Ein Tupel, das die Typparameter einer generischen Funktion enthält.

Hinzugefügt in Version 3.12.

Funktionsobjekte unterstützen auch das Abrufen und Setzen beliebiger Attribute, die beispielsweise verwendet werden können, um Metadaten an Funktionen anzuhängen. Reguläre Punktnotation wird verwendet, um solche Attribute abzurufen und zu setzen.

CPython-Implementierungsdetail: Die aktuelle CPython-Implementierung unterstützt Funktionsattribute nur für benutzerdefinierte Funktionen. Funktionsattribute für eingebaute Funktionen können in Zukunft unterstützt werden.

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

3.2.8.2. Instanzmethoden

Ein Instanzmethodenobjekt kombiniert eine Klasse, eine Klasseninstanz und ein beliebiges aufrufbares Objekt (normalerweise eine benutzerdefinierte Funktion).

Spezielle schreibgeschützte Attribute

method.__self__

Verweist auf das Klasseninstanzobjekt, an das die Methode gebunden ist.

method.__func__

Verweist auf das ursprüngliche Funktionsobjekt.

method.__doc__

Die Dokumentation der Methode (wie method.__func__.__doc__). Ein String, wenn die ursprüngliche Funktion einen Docstring hatte, andernfalls None.

method.__name__

Der Name der Methode (wie method.__func__.__name__).

method.__module__

Der Name des Moduls, in dem die Methode definiert wurde, oder None, falls nicht verfügbar.

Methoden unterstützen auch den Zugriff auf (aber nicht das Setzen von) beliebigen Funktionsattributen des zugrunde liegenden Funktionsobjekts.

Benutzerdefinierte Methodenobjekte können erstellt werden, wenn ein Attribut einer Klasse abgerufen wird (möglicherweise über eine Instanz dieser Klasse), wenn dieses Attribut ein benutzerdefiniertes Funktionsobjekt oder ein classmethod-Objekt ist.

Wenn ein Instanzmethodenobjekt durch Abrufen eines benutzerdefinierten Funktionsobjekts aus einer Klasse über eine ihrer Instanzen erstellt wird, ist sein Attribut __self__ die Instanz, und das Methodenobjekt wird als *gebunden* bezeichnet. Das Attribut __func__ der neuen Methode ist das ursprüngliche Funktionsobjekt.

Wenn ein Instanzmethodenobjekt durch Abrufen eines classmethod-Objekts von 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 der Argumentliste eingefügt wird. Wenn beispielsweise C eine Klasse ist, die eine Definition für eine Funktion f() enthält, und x eine Instanz von C ist, ist der Aufruf von x.f(1) äquivalent zu C.f(x, 1).

Wenn ein Instanzmethodenobjekt aus einem classmethod-Objekt abgeleitet wird, ist die in __self__ gespeicherte "Klasseninstanz" tatsächlich die Klasse selbst, sodass der Aufruf von x.f(1) oder C.f(1) äquivalent zu f(C,1) ist, wobei f die zugrunde liegende Funktion ist.

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

3.2.8.3. Generatorfunktionen

Eine Funktion oder Methode, die die yield-Anweisung verwendet (siehe Abschnitt Die yield-Anweisung), wird als *Generatorfunktion* bezeichnet. Eine solche Funktion gibt beim Aufruf immer ein Iterator-Objekt zurück, das verwendet werden kann, um den Körper der Funktion auszuführen: das Aufrufen der Methode iterator.__next__() führt dazu, dass die Funktion ausgeführt wird, bis sie einen Wert über die yield-Anweisung liefert. Wenn die Funktion eine return-Anweisung ausführt oder das Ende erreicht, wird eine StopIteration-Ausnahme ausgelöst und der Iterator hat das Ende der zu liefernden Werte erreicht.

3.2.8.4. Koroutinenfunktionen

Eine Funktion oder Methode, die mit async def definiert ist, wird als *Koroutinenfunktion* bezeichnet. Eine solche Funktion gibt beim Aufruf ein Koroutinen-Objekt zurück. Sie kann await-Ausdrücke sowie async with- und async for-Anweisungen enthalten. Siehe auch den Abschnitt Koroutinenobjekte.

3.2.8.5. Asynchrone Generatorfunktionen

Eine Funktion oder Methode, die mit async def definiert ist und die yield-Anweisung verwendet, wird als *asynchrone Generatorfunktion* bezeichnet. Eine solche Funktion gibt beim Aufruf ein asynchrones Iterator-Objekt zurück, das in einer async for-Anweisung verwendet werden kann, um den Körper der Funktion auszuführen.

Der Aufruf der Methode aiterator.__anext__ des asynchronen Iterators gibt ein Awaitable zurück, das beim Warten die Funktion ausführt, bis sie einen Wert über den yield-Ausdruck liefert. Wenn die Funktion eine leere return-Anweisung ausführt oder das Ende erreicht, wird eine StopAsyncIteration-Ausnahme ausgelöst und das asynchrone Iterator hat das Ende der zu liefernden Werte erreicht.

3.2.8.6. Eingebaute Funktionen

Ein eingebautes Funktionsobjekt ist ein Wrapper um eine C-Funktion. Beispiele für eingebaute Funktionen sind len() und math.sin() (math ist ein Standard-eingebautes Modul). Die Anzahl und Art der Argumente werden von der C-Funktion bestimmt. Spezielle schreibgeschützte Attribute

  • __doc__ ist der Dokumentationsstring der Funktion oder None, falls nicht verfügbar. Siehe function.__doc__.

  • __name__ ist der Name der Funktion. Siehe function.__name__.

  • __self__ ist auf None gesetzt (aber siehe nächster Punkt).

  • __module__ ist der Name des Moduls, in dem die Funktion definiert wurde, oder None, falls nicht verfügbar. Siehe function.__module__.

3.2.8.7. Eingebaute Methoden

Dies ist eigentlich eine andere Erscheinungsform einer eingebauten Funktion, die diesmal ein Objekt enthält, das der C-Funktion als implizites zusätzliches Argument übergeben wird. Ein Beispiel für eine eingebaute Methode ist alist.append(), vorausgesetzt, *alist* ist ein Listenobjekt. In diesem Fall ist das spezielle schreibgeschützte Attribut __self__ auf das von *alist* bezeichnete Objekt gesetzt. (Das Attribut hat die gleiche Semantik wie bei anderen Instanzmethoden.)

3.2.8.8. Klassen

Klassen sind aufrufbar. Diese Objekte fungieren normalerweise als Fabriken für neue Instanzen von sich selbst, aber Variationen sind für Klassentypen möglich, die __new__() überschreiben. 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 eine Methode __call__() in ihrer Klasse definiert wird.

3.2.9. Module

Module sind eine grundlegende Organisationseinheit von Python-Code und werden vom Importsystem erstellt, entweder durch die Anweisung import oder durch Aufruf von Funktionen wie importlib.import_module() und die eingebaute Funktion __import__(). Ein Modulobjekt hat einen Namensraum, der durch ein Dictionary-Objekt implementiert ist (dies ist das Dictionary, auf das im Attribut __globals__ von Funktionen verwiesen wird, die im Modul definiert sind). Attributreferenzen werden in Lookups in diesem Dictionary übersetzt, z. B. ist m.x äquivalent zu m.__dict__["x"]. Ein Modulobjekt enthält nicht das Code-Objekt, das zur Initialisierung des Moduls verwendet wird (da es nach Abschluss der Initialisierung nicht mehr benötigt wird).

Attributzuweisungen aktualisieren das Namensraum-Dictionary des Moduls, z. B. ist m.x = 1 äquivalent zu m.__dict__["x"] = 1.

3.2.9.2. Andere beschreibbare Attribute von Module-Objekten

Neben den oben aufgeführten Import-bezogenen Attributen haben Modulobjekte auch die folgenden beschreibbaren Attribute:

module.__doc__

Die Dokumentationszeichenkette des Moduls oder None, wenn nicht verfügbar. Siehe auch: __doc__ Attribute.

module.__annotations__

Ein Wörterbuch, das Variablenannotationen enthält, die während der Ausführung des Modulkörpers gesammelt wurden. Die besten Praktiken für die Arbeit mit __annotations__ finden Sie in annotationlib.

Geändert in Version 3.14: Annotationen werden jetzt lazy ausgewertet. Siehe PEP 649.

module.__annotate__

Die Annotate-Funktion für dieses Modul oder None, wenn das Modul keine Annotationen hat. Siehe auch: __annotate__ Attribute.

Hinzugefügt in Version 3.14.

3.2.9.3. Modul-Wörterbücher

Modulobjekte haben auch das folgende spezielle schreibgeschützte Attribut:

module.__dict__

Der Namensraum des Moduls als Wörterbuchobjekt. Einzigartig unter den hier aufgeführten Attributen kann __dict__ nicht als globale Variable innerhalb eines Moduls zugegriffen werden; es kann nur als Attribut von Modulobjekten zugegriffen werden.

CPython-Implementierungsdetail: Aufgrund der Art und Weise, wie CPython Modul-Wörterbücher löscht, wird das Modul-Wörterbuch gelöscht, wenn das Modul aus dem Geltungsbereich fällt, auch wenn das Wörterbuch noch Live-Referenzen hat. Um dies zu vermeiden, kopieren Sie das Wörterbuch oder behalten Sie das Modul bei, während Sie direkt auf sein Wörterbuch zugreifen.

3.2.10. Benutzerdefinierte Klassen

Benutzerdefinierte Klassentypen werden typischerweise durch Klassendefinitionen erstellt (siehe Abschnitt Klassendefinitionen). Eine Klasse hat einen Namensraum, der durch ein Wörterbuchobjekt implementiert wird. Klassenattributreferenzen werden in Lookups in diesem Wörterbuch übersetzt, z. B. wird C.x in C.__dict__["x"] übersetzt (obwohl es eine Reihe von Hooks gibt, die andere Mittel zur Lokalisierung von Attributen ermöglichen). Wenn der Attributname dort nicht gefunden wird, wird die Attributsuche in den Basisklassen fortgesetzt. Diese Suche in den Basisklassen verwendet die C3-Methodenauflösungsreihenfolge, die auch bei 'diamond'-Vererbungsszenarien korrekt funktioniert, bei denen mehrere Vererbungspfade zu einem gemeinsamen Vorfahren zurückführen. Zusätzliche Details zur von Python verwendeten C3 MRO finden Sie unter Die Python 2.3 Method Resolution Order.

Wenn eine Klassenattributreferenz (für die Klasse C, z. B.) ein Klassenmethodenobjekt ergibt, wird es in ein Instanzmethodenobjekt umgewandelt, dessen __self__-Attribut C ist. Wenn es ein staticmethod-Objekt ergibt, wird es in das vom statischen Methodenobjekt umschlossene Objekt umgewandelt. Siehe Abschnitt Implementierung von Deskriptoren für eine weitere Möglichkeit, wie Attribute, die von einer Klasse abgerufen werden, von denen abweichen können, die tatsächlich in ihrem __dict__ enthalten sind.

Klassenattributzuweisungen aktualisieren das Wörterbuch der Klasse, niemals das Wörterbuch einer Basisklasse.

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

3.2.10.1. Spezielle Attribute

Attribut

Bedeutung

type.__name__

Der Name der Klasse. Siehe auch: __name__ Attribute.

type.__qualname__

Der qualifizierte Name der Klasse. Siehe auch: __qualname__ Attribute.

type.__module__

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

type.__dict__

Ein Mapping-Proxy, der eine schreibgeschützte Ansicht des Namensraums der Klasse bietet. Siehe auch: __dict__ Attribute.

type.__bases__

Ein Tupel, das die Basen der Klasse enthält. In den meisten Fällen ist für eine Klasse, die als class X(A, B, C) definiert ist, X.__bases__ exakt gleich (A, B, C).

type.__doc__

Die Dokumentationszeichenkette der Klasse oder None, wenn nicht definiert. Wird nicht von Unterklassen geerbt.

type.__annotations__

Ein Wörterbuch, das Variablenannotationen enthält, die während der Ausführung des Klassenkörpers gesammelt wurden. Siehe auch: __annotations__ Attribute.

Die besten Praktiken für die Arbeit mit __annotations__ finden Sie in annotationlib. Verwenden Sie annotationlib.get_annotations(), anstatt direkt auf dieses Attribut zuzugreifen.

Warnung

Der direkte Zugriff auf das Attribut __annotations__ eines Klassenobjekts kann Annotationen für die falsche Klasse zurückgeben, insbesondere in bestimmten Fällen, in denen die Klasse, ihre Basisklasse oder eine Metaklasse unter from __future__ import annotations definiert ist. Einzelheiten finden Sie unter PEP 749.

Dieses Attribut existiert nicht auf bestimmten eingebauten Klassen. Auf benutzerdefinierten Klassen ohne __annotations__ ist es ein leeres Wörterbuch.

Geändert in Version 3.14: Annotationen werden jetzt lazy ausgewertet. Siehe PEP 649.

type.__annotate__()

Die Annotate-Funktion für diese Klasse oder None, wenn die Klasse keine Annotationen hat. Siehe auch: __annotate__ Attribute.

Hinzugefügt in Version 3.14.

type.__type_params__

Ein Tupel, das die Typparameter einer generischen Klasse enthält.

Hinzugefügt in Version 3.12.

type.__static_attributes__

Ein Tupel, das Namen von Attributen dieser Klasse enthält, die über self.X aus einer Funktion in ihrem Körper zugewiesen werden.

Hinzugefügt in Version 3.13.

type.__firstlineno__

Die Zeilennummer der ersten Zeile der Klassendefinition, einschließlich Dekoratoren. Das Setzen des Attributs __module__ entfernt das Element __firstlineno__ aus dem Wörterbuch des Typs.

Hinzugefügt in Version 3.13.

type.__mro__

Das Tupel von Klassen, die bei der Suche nach Basisklassen während der Methodenauflösung berücksichtigt werden.

3.2.10.2. Spezielle Methoden

Zusätzlich zu den oben beschriebenen speziellen Attributen verfügen alle Python-Klassen auch über die folgenden beiden Methoden:

type.mro()

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

type.__subclasses__()

Jede Klasse verwaltet eine Liste von schwachen Referenzen auf ihre unmittelbaren Unterklassen. Diese Methode gibt eine Liste aller noch lebenden Referenzen zurück. Die Liste ist in der Reihenfolge der Definition. Beispiel:

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

3.2.11. Klasseninstanzen

Eine Klasseninstanz wird durch Aufrufen eines Klassenobjekts (siehe oben) erstellt. Eine Klasseninstanz hat einen Namensraum, der als Wörterbuch implementiert ist und der erste Ort ist, an dem Attributreferenzen gesucht werden. Wenn ein Attribut dort nicht gefunden wird und die Klasse der Instanz ein Attribut mit diesem Namen hat, wird die Suche mit den Klassenattributen fortgesetzt. Wenn ein Klassenattribut gefunden wird, das ein benutzerdefiniertes Funktionsobjekt ist, wird es in ein Instanzmethodenobjekt umgewandelt, dessen __self__-Attribut die Instanz ist. Statische Methoden- und Klassenmethodenobjekte werden ebenfalls umgewandelt; siehe oben unter „Klassen“. Siehe Abschnitt Implementierung von Deskriptoren für eine weitere Möglichkeit, wie Attribute einer Klasse, die über ihre Instanzen abgerufen werden, von den Objekten abweichen können, die tatsächlich im __dict__ der Klasse gespeichert sind. Wenn kein Klassenattribut gefunden wird und die Klasse des Objekts eine __getattr__()-Methode hat, wird diese aufgerufen, um die Suche zu erfüllen.

Attributzuweisungen und -löschungen aktualisieren das Wörterbuch der Instanz, niemals das Wörterbuch einer Klasse. Wenn die Klasse eine __setattr__()- oder __delattr__()-Methode hat, wird diese anstelle der direkten Aktualisierung des Instanzwörterbuchs aufgerufen.

Klasseninstanzen können sich wie Zahlen, Sequenzen oder Wörterbücher verhalten, wenn sie Methoden mit bestimmten speziellen Namen haben. Siehe Abschnitt Spezielle Methodennamen.

3.2.11.1. Spezielle Attribute

object.__class__

Die Klasse, zu der eine Klasseninstanz gehört.

object.__dict__

Ein Wörterbuch oder ein anderes Mapping-Objekt, das zur Speicherung der (beschreibbaren) Attribute eines Objekts verwendet wird. Nicht alle Instanzen haben ein __dict__-Attribut; siehe Abschnitt __slots__ für weitere Details.

3.2.12. E/A-Objekte (auch bekannt als Dateiobjekte)

Ein Dateiobjekt repräsentiert eine geöffnete Datei. Verschiedene Verknüpfungen sind verfügbar, um Dateiobjekte zu erstellen: die eingebaute Funktion open(), und auch os.popen(), os.fdopen() und die makefile()-Methode von Socket-Objekten (und vielleicht von anderen Funktionen oder Methoden, die von Erweiterungsmodulen bereitgestellt werden).

Die Objekte sys.stdin, sys.stdout und sys.stderr sind mit Dateiobjekten initialisiert, die den Standard-Ein-, Aus- und Fehlerströmen des Interpreters entsprechen; sie sind alle im Textmodus geöffnet und folgen daher der von der abstrakten Klasse io.TextIOBase definierten Schnittstelle.

3.2.13. Interne Typen

Einige vom Interpreter intern verwendete Typen werden dem Benutzer zugänglich gemacht. Ihre Definitionen können sich mit zukünftigen Versionen des Interpreters ändern, sie werden jedoch der Vollständigkeit halber hier erwähnt.

3.2.13.1. Code-Objekte

Code-Objekte repräsentieren *Byte-kompilierten* ausführbaren Python-Code oder Bytecode. Der Unterschied zwischen einem Code-Objekt und einem Funktions-Objekt besteht darin, dass das Funktions-Objekt eine explizite Referenz auf die Globale der Funktion (das Modul, in dem sie definiert wurde) enthält, während ein Code-Objekt keinen Kontext enthält; außerdem werden die Standardargumentwerte im Funktions-Objekt gespeichert, nicht im Code-Objekt (da sie Laufzeitwerte darstellen). Im Gegensatz zu Funktions-Objekten sind Code-Objekte unveränderlich und enthalten keine (direkten oder indirekten) Referenzen auf veränderliche Objekte.

3.2.13.1.1. Spezielle schreibgeschützte Attribute
codeobject.co_name

Der Funktionsname.

codeobject.co_qualname

Der qualifizierte Funktionsname.

Hinzugefügt in Version 3.11.

codeobject.co_argcount

Die Gesamtzahl der positionsbezogenen Parameter (einschließlich positionsbezogener Parameter und Parameter mit Standardwerten), die die Funktion hat.

codeobject.co_posonlyargcount

Die Anzahl der positionsbezogenen Parameter (einschließlich Argumente mit Standardwerten), die die Funktion hat.

codeobject.co_kwonlyargcount

Die Anzahl der Schlüsselwort-only Parameter (einschließlich Argumente mit Standardwerten), die die Funktion hat.

codeobject.co_nlocals

Die Anzahl der lokalen Variablen, die von der Funktion verwendet werden (einschließlich Parametern).

codeobject.co_varnames

Ein Tupel, das die Namen der lokalen Variablen in der Funktion enthält (beginnend mit den Parameternamen).

codeobject.co_cellvars

Ein Tupel, das die Namen von lokalen Variablen enthält, auf die mindestens ein verschachtelter Geltungsbereich innerhalb der Funktion verweist

codeobject.co_freevars

Ein Tupel, das die Namen von freien (Closure-)Variablen enthält, auf die ein verschachtelter Geltungsbereich in einem äußeren Geltungsbereich verweist. Siehe auch function.__closure__.

Hinweis: Verweise auf globale und eingebaute Namen sind nicht enthalten.

codeobject.co_code

Ein String, der die Sequenz von Bytecode-Instruktionen in der Funktion darstellt

codeobject.co_consts

Ein Tupel, das die Literale enthält, die vom Bytecode in der Funktion verwendet werden

codeobject.co_names

Ein Tupel, das die Namen enthält, die vom 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. Details finden Sie im Quellcode des Interpreters.

Veraltet seit Version 3.12: Dieses Attribut von Code-Objekten ist veraltet und könnte in Python 3.15 entfernt werden.

codeobject.co_stacksize

Die erforderliche Stack-Größe des Code-Objekts

codeobject.co_flags

Ein Integer, der eine Anzahl von Flags für den Interpreter kodiert.

Die folgenden Flag-Bits sind für co_flags definiert: Bit 0x04 ist gesetzt, wenn die Funktion die Syntax *arguments verwendet, um eine beliebige Anzahl von Positionsargumenten zu akzeptieren; Bit 0x08 ist gesetzt, wenn die Funktion die Syntax **keywords verwendet, um beliebige Schlüsselwortargumente zu akzeptieren; Bit 0x20 ist gesetzt, wenn die Funktion ein Generator ist. Details zur Semantik der einzelnen Flags finden Sie unter Code-Objekt-Bit-Flags.

Zukünftige Feature-Deklarationen (z.B. from __future__ import division) verwenden ebenfalls Bits in co_flags, um anzuzeigen, ob ein Code-Objekt mit einem bestimmten Feature kompiliert wurde. Siehe compiler_flag.

Andere Bits in co_flags sind für die interne Verwendung reserviert.

Wenn ein Code-Objekt eine Funktion darstellt und eine Docstring hat, ist das Bit CO_HAS_DOCSTRING in co_flags gesetzt und das erste Element in co_consts ist die Docstring der Funktion.

3.2.13.1.2. Methoden für Code-Objekte
codeobject.co_positions()

Gibt ein iterierbares Objekt zurück, das die Quellcode-Positionen jeder Bytecode-Instruktion im Code-Objekt enthält.

Der Iterator gibt Tupel zurück, die (start_line, end_line, start_column, end_column) enthalten. Das i-te Tupel entspricht der Position des Quellcodes, der zu der i-ten Code-Einheit kompiliert wurde. Spalteninformationen sind 0-indizierte UTF-8-Byte-Offsets in der angegebenen Quellzeile.

Diese Positionsinformationen können fehlen. Eine nicht erschöpfende Liste von Fällen, in denen dies geschehen kann

  • Der Interpreter wird mit -X no_debug_ranges ausgeführt.

  • Laden einer pyc-Datei, die während der Verwendung von -X no_debug_ranges kompiliert wurde.

  • Positions-Tupel, die künstlichen Instruktionen entsprechen.

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

In diesem Fall können einige oder alle Tupel-Elemente None sein.

Hinzugefügt in Version 3.11.

Hinweis

Diese Funktion erfordert die Speicherung von Spaltenpositionen in Code-Objekten, was zu einer geringfügigen Erhöhung des Speicherbedarfs kompilierter Python-Dateien oder des Speicherbedarfs des Interpreters führen kann. Um die zusätzlichen Informationen nicht zu speichern und/oder die Ausgabe zusätzlicher Traceback-Informationen zu deaktivieren, können die Kommandozeilenoption -X no_debug_ranges oder die Umgebungsvariable PYTHONNODEBUGRANGES verwendet werden.

codeobject.co_lines()

Gibt einen Iterator zurück, der Informationen über aufeinanderfolgende Bereiche von Bytecodes liefert. Jedes ausgegebene Element ist ein (start, end, lineno) Tupel

  • start (ein Integer) repräsentiert den Offset (inklusiv) des Beginns des Bytecode-Bereichs

  • end (ein Integer) repräsentiert den Offset (exklusiv) des Endes des Bytecode-Bereichs

  • lineno ist ein Integer, der die Zeilennummer des Bytecode-Bereichs darstellt, oder None, wenn die Bytecodes im gegebenen Bereich keine Zeilennummer haben

Die ausgegebenen Elemente haben folgende Eigenschaften

  • Der erste ausgegebene Bereich hat einen start von 0.

  • Die (start, end)-Bereiche sind nicht abnehmend und aufeinanderfolgend. Das heißt, für jedes Paar von Tupeln ist der start des zweiten gleich dem end des ersten.

  • Kein Bereich ist rückwärts: end >= start für alle Tripel.

  • Das letzte ausgegebene Tupel hat end gleich der Größe des Bytecodes.

Bereiche mit Null-Breite, bei denen start == end ist, sind zulässig. Bereiche mit Null-Breite werden für Zeilen verwendet, die im Quellcode vorhanden sind, aber vom Bytecode-Compiler eliminiert wurden.

Hinzugefügt in Version 3.10.

Siehe auch

PEP 626 - Genaue Zeilennummern für Debugging und andere Werkzeuge.

Die PEP, die die Methode co_lines() eingeführt hat.

codeobject.replace(**kwargs)

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

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

Hinzugefügt in Version 3.8.

3.2.13.2. Frame-Objekte

Frame-Objekte repräsentieren Ausführungs-Frames. Sie können in Traceback-Objekten auftreten und werden auch an registrierte Trace-Funktionen übergeben.

3.2.13.2.1. Spezielle schreibgeschützte Attribute
frame.f_back

Verweist auf den vorherigen Stack-Frame (in Richtung Aufrufer) oder 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 Audit-Ereignis object.__getattr__ mit den Argumenten obj und "f_code" aus.

frame.f_locals

Die Zuordnung, die vom Frame verwendet wird, um lokale Variablen nachzuschlagen. Wenn der Frame auf einen optimierten Geltungsbereich verweist, kann dies ein Write-Through-Proxy-Objekt zurückgeben.

Geändert in Version 3.13: Gibt einen Proxy für optimierte Geltungsbereiche zurück.

frame.f_globals

Das Dictionary, das vom Frame zum Nachschlagen von globalen Variablen verwendet wird

frame.f_builtins

Das Dictionary, das vom Frame zum Nachschlagen von eingebauten (intrinsischen) Namen verwendet wird

frame.f_lasti

Die „präzise Instruktion“ des Frame-Objekts (dies ist ein Index in die Bytecode-Zeichenkette des Code-Objekts)

frame.f_generator

Das Generator- oder Coroutine-Objekt, dem dieser Frame gehört, oder None, wenn der Frame eine normale Funktion ist.

Hinzugefügt in Version 3.14.

3.2.13.2.2. Spezielle beschreibbare Attribute
frame.f_trace

Wenn nicht None, ist dies eine Funktion, die für verschiedene Ereignisse während der Codeausführung aufgerufen wird (dies wird von Debuggern verwendet). Normalerweise wird für jede neue Quellzeile ein Ereignis ausgelöst (siehe f_trace_lines).

frame.f_trace_lines

Setzen Sie dieses Attribut auf False, um das Auslösen eines Trace-Ereignisses für jede Quellzeile zu deaktivieren.

frame.f_trace_opcodes

Setzen Sie dieses Attribut auf True, um pro Opcode ausgelöste Ereignisse anzufordern. Beachten Sie, dass dies zu undefiniertem Interpreterverhalten führen kann, wenn durch die Trace-Funktion ausgelöste Ausnahmen in die verfolgte Funktion entweichen.

frame.f_lineno

Die aktuelle Zeilennummer des Frames – Schreiben in dieses Attribut von innerhalb einer Trace-Funktion springt zur angegebenen Zeile (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. Frame-Objekt-Methoden

Frame-Objekte unterstützen eine Methode

frame.clear()

Diese Methode löscht alle Referenzen auf lokale Variablen, die vom Frame gehalten werden. Wenn der Frame zu einem Generator gehörte, wird der Generator auch finalisiert. Dies hilft, Referenzzyklen zu brechen, die Frame-Objekte betreffen (z.B. beim Abfangen einer Ausnahme und Speichern ihres Tracebacks für spätere Verwendung).

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

Hinzugefügt in Version 3.4.

Geändert in Version 3.13: Der Versuch, einen suspendierten Frame zu löschen, löst RuntimeError aus (wie es für ausgeführte Frames immer der Fall war).

3.2.13.3. Traceback-Objekte

Traceback-Objekte repräsentieren den Stack-Trace einer Ausnahme. Ein Traceback-Objekt wird implizit erstellt, wenn eine Ausnahme auftritt, und kann auch explizit durch Aufrufen von types.TracebackType erstellt werden.

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

Für implizit erstellte Tracebacks wird bei der Suche nach einem Ausnahmebehandler, der den Ausführungs-Stack entwirrt, auf jeder entwirrten Ebene ein Traceback-Objekt vor dem aktuellen Traceback eingefügt. Wenn ein Ausnahmebehandler betreten 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 und als Attribut __traceback__ der abgefangenen Ausnahme zugänglich.

Wenn das Programm keinen geeigneten Behandler enthält, wird der Stack-Trace (schön formatiert) auf den Standardfehlerstrom geschrieben; wenn der Interpreter interaktiv ist, wird er dem Benutzer auch als sys.last_traceback zur Verfügung gestellt.

Für explizit erstellte Tracebacks obliegt es dem Ersteller des Tracebacks, zu bestimmen, wie die Attribute tb_next verknüpft werden sollen, um einen vollständigen Stack-Trace zu bilden.

Spezielle schreibgeschützte Attribute

traceback.tb_frame

Verweist auf den Ausführungs-Frame der aktuellen Ebene.

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

Gibt die „präzise Instruktion“ an.

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

traceback.tb_next

Das spezielle beschreibbare Attribut tb_next ist die nächste Ebene im Stack-Trace (in Richtung des Frames, in dem die Ausnahme aufgetreten ist), oder None, wenn keine nächste Ebene vorhanden ist.

Geändert in Version 3.7: Dieses Attribut ist jetzt beschreibbar

3.2.13.4. Slice-Objekte

Slice-Objekte werden verwendet, um Slices für __getitem__()-Methoden darzustellen. Sie werden auch von der eingebauten Funktion slice() erstellt.

Spezielle schreibgeschützte Attribute: start ist die untere Grenze; stop ist die obere Grenze; step ist der Schrittwert; jeder ist None, wenn er weggelassen wird. Diese Attribute können jeden Typ haben.

Slice-Objekte unterstützen eine Methode

slice.indices(self, length)

Diese Methode nimmt ein einzelnes ganzzahliges Argument length und berechnet Informationen über den Slice, den das Slice-Objekt beschreiben würde, wenn es auf eine Sequenz von length Elementen angewendet wird. Sie gibt ein Tupel von drei ganzen Zahlen zurück; dies sind jeweils der Start- und Stop-Index sowie die Schrittweite oder Schrittlänge des Slices. Fehlende oder außerhalb des Bereichs liegende Indizes werden konsistent mit regulären Slices behandelt.

3.2.13.5. Static-Methoden-Objekte

Static-Methoden-Objekte bieten eine Möglichkeit, die Transformation von Funktions-Objekten in Methoden-Objekte zu verhindern, wie oben beschrieben. Ein Static-Methoden-Objekt ist ein Wrapper um ein beliebiges anderes Objekt, normalerweise ein benutzerdefiniertes Methoden-Objekt. Wenn ein Static-Methoden-Objekt von einer Klasse oder einer Klasseninstanz abgerufen wird, ist das tatsächlich zurückgegebene Objekt das verpackte Objekt, das keiner weiteren Transformation unterliegt. Static-Methoden-Objekte sind ebenfalls aufrufbar. Static-Methoden-Objekte werden vom eingebauten Konstruktor staticmethod() erstellt.

3.2.13.6. Klassenmethoden-Objekte

Ein Klassenmethoden-Objekt ist, ähnlich einem Static-Methoden-Objekt, ein Wrapper um ein anderes Objekt, das die Art und Weise verändert, wie dieses Objekt von Klassen und Klasseninstanzen abgerufen wird. Das Verhalten von Klassenmethoden-Objekten bei einem solchen Abruf wird oben unter „Instanzmethoden“ beschrieben. Klassenmethoden-Objekte werden vom eingebauten Konstruktor classmethod() erstellt.

3.3. Spezielle Methodennamen

Eine Klasse kann bestimmte Operationen implementieren, die durch spezielle Syntax aufgerufen werden (wie 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 ist x[i] ungefähr äquivalent zu type(x).__getitem__(x, i). Sofern nicht anders angegeben, wird beim Versuch, eine Operation auszuführen, eine Ausnahme ausgelöst, wenn keine geeignete Methode definiert ist (typischerweise AttributeError oder TypeError).

Das Setzen einer speziellen Methode auf None zeigt an, dass die entsprechende Operation nicht verfügbar ist. Wenn eine Klasse beispielsweise __iter__() auf None setzt, ist die Klasse nicht iterierbar, sodass das Aufrufen von iter() für ihre Instanzen eine TypeError auslöst (ohne auf __getitem__() zurückzufallen). [2]

Beim Implementieren einer Klasse, die einen eingebauten Typ emuliert, ist es wichtig, dass die Emulation nur in dem Maße implementiert wird, wie es für das modellierte Objekt sinnvoll ist. Beispielsweise können einige Sequenzen gut mit dem Abrufen einzelner Elemente funktionieren, aber das Extrahieren eines Slices ist möglicherweise nicht sinnvoll. (Ein Beispiel hierfür ist die NodeList-Schnittstelle im Document Object Model des W3C.)

3.3.1. Grundlegende Anpassung

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

Wird aufgerufen, um eine neue Instanz der Klasse cls zu erstellen. __new__() ist eine statische Methode (speziell behandelt, sodass Sie sie nicht als solche deklarieren müssen), die die Klasse, für die eine Instanz angefordert wurde, als erstes Argument nimmt. Die restlichen Argumente sind diejenigen, die dem Ausdruck zur Objekterstellung übergeben werden (dem Aufruf der Klasse). Der Rückgabewert von __new__() sollte die neue Instanz des Objekts sein (normalerweise eine Instanz von cls).

Typische Implementierungen erstellen eine neue Instanz der Klasse, indem sie die __new__()-Methode der Oberklasse mit super().__new__(cls[, ...]) mit geeigneten Argumenten aufrufen und dann die neu erstellte Instanz nach Bedarf ändern, bevor sie zurückgegeben wird.

Wenn __new__() während der Objekterstellung aufgerufen wird und eine Instanz von cls zurückgibt, dann wird die __init__()-Methode der neuen Instanz wie folgt aufgerufen: __init__(self[, ...]), wobei self die neue Instanz ist und die verbleibenden Argumente dieselben sind, die an den Objektkonstruktor übergeben wurden.

Wenn __new__() keine Instanz von cls zurückgibt, dann wird die __init__()-Methode der neuen Instanz nicht aufgerufen.

__new__() ist hauptsächlich dazu gedacht, Unterklassen unveränderlicher Typen (wie int, str oder tuple) die Anpassung der Instanzerstellung zu ermöglichen. Es wird auch häufig in benutzerdefinierten Metaklassen überschrieben, um die Klassenerstellung anzupassen.

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

Wird aufgerufen, nachdem die Instanz erstellt wurde (durch __new__()), aber bevor sie an den Aufrufer zurückgegeben wird. Die Argumente sind diejenigen, die dem Konstruktorausdruck der Klasse übergeben wurden. Wenn eine Basisklasse eine __init__()-Methode hat, muss die __init__()-Methode der abgeleiteten Klasse, falls vorhanden, diese explizit aufrufen, um die ordnungsgemäße Initialisierung des Basisklassen-Teils der Instanz sicherzustellen; zum Beispiel: super().__init__([args...]).

Da __new__() und __init__() bei der Konstruktion von Objekten zusammenarbeiten (__new__() zum Erstellen, und __init__() zum Anpassen), darf von __init__() kein anderer Wert als None zurückgegeben werden; andernfalls wird zur Laufzeit ein TypeError ausgelöst.

object.__del__(self)

Wird aufgerufen, wenn die Instanz zerstört werden soll. Dies wird auch als Finalizer oder (fälschlicherweise) als Destruktor bezeichnet. Wenn eine Basisklasse eine __del__()-Methode hat, muss die __del__()-Methode der abgeleiteten Klasse, falls vorhanden, diese explizit aufrufen, um die ordnungsgemäße Zerstörung des Basisklassen-Teils der Instanz sicherzustellen.

Es ist möglich (wenn auch nicht empfohlen!), dass die __del__()-Methode die Zerstörung der Instanz hinauszögert, indem sie eine neue Referenz darauf erstellt. Dies wird als Auferstehung des Objekts bezeichnet. Es ist implementierungsabhängig, ob __del__() bei der Zerstörung eines auferstandenen Objekts ein zweites Mal aufgerufen wird; die aktuelle CPython-Implementierung ruft sie nur einmal auf.

Es ist nicht garantiert, dass __del__()-Methoden für Objekte aufgerufen werden, die noch existieren, wenn der Interpreter beendet wird. weakref.finalize bietet eine einfache Möglichkeit, eine Bereinigungsfunktion zu registrieren, die aufgerufen wird, wenn ein Objekt vom Garbage Collector eingesammelt wird.

Hinweis

del x ruft x.__del__() nicht direkt auf – ersteres dekrementiert den Referenzzähler für x um eins, und letzteres wird nur aufgerufen, wenn der Referenzzähler von x null erreicht.

CPython-Implementierungsdetail: Es ist möglich, dass ein Referenzzyklus verhindert, dass der Referenzzähler eines Objekts auf null fällt. 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 Variable abgefangen wurde. Die Locals des Frames referenzieren dann die Ausnahme, die ihre eigene Traceback referenziert, die die Locals aller im Traceback abgefangenen Frames referenziert.

Siehe auch

Dokumentation für das Modul gc.

Warnung

Aufgrund der prekären Umstände, unter denen __del__()-Methoden aufgerufen werden, werden Ausnahmen, die während ihrer Ausführung auftreten, ignoriert und stattdessen eine Warnung auf sys.stderr ausgegeben. Insbesondere

  • __del__() kann aufgerufen werden, wenn beliebiger Code ausgeführt wird, einschließlich Code von einem beliebigen Thread. Wenn __del__() eine Sperre ergreifen oder eine andere blockierende Ressource aufrufen muss, kann es zu einer Deadlock-Situation kommen, da die Ressource möglicherweise bereits vom Code belegt ist, der unterbrochen wird, um __del__() auszuführen.

  • __del__() kann während der Beendigung des Interpreters ausgeführt werden. Infolgedessen können globale Variablen, auf die es zugreifen muss (einschließlich anderer Module), bereits gelöscht oder auf None gesetzt worden sein. Python garantiert, dass globale Variablen, deren Name mit einem einzelnen Unterstrich beginnt, vor anderen globalen Variablen aus ihrem Modul gelöscht werden; wenn keine anderen Referenzen auf solche globalen Variablen existieren, kann dies dazu beitragen, dass importierte Module zum Zeitpunkt des Aufrufs der __del__()-Methode noch verfügbar sind.

object.__repr__(self)

Wird von der eingebauten Funktion repr() aufgerufen, um die „offizielle“ Zeichenkettenrepräsentation eines Objekts zu berechnen. Wenn möglich, sollte dies wie ein gültiger Python-Ausdruck aussehen, der verwendet werden könnte, um ein Objekt mit demselben Wert (in einer geeigneten Umgebung) neu zu erstellen. Wenn dies nicht möglich ist, sollte ein String der Form <...irgendeine nützliche Beschreibung...> zurückgegeben werden. Der Rückgabewert muss ein Zeichenkettenobjekt sein. Wenn eine Klasse __repr__(), aber nicht __str__() definiert, dann wird __repr__() auch verwendet, wenn eine „informelle“ Zeichenkettenrepräsentation von Instanzen dieser Klasse erforderlich ist.

Dies wird typischerweise für Debuggingzwecke verwendet, daher ist es wichtig, dass die Darstellung informativ und eindeutig ist. Eine Standardimplementierung wird von der Klasse object selbst bereitgestellt.

object.__str__(self)

Wird von str(object), der Standardimplementierung von __format__() und der eingebauten Funktion print() aufgerufen, um die „informelle“ oder gut lesbare Zeichenkettenrepräsentation eines Objekts zu berechnen. Der Rückgabewert muss ein str-Objekt sein.

Diese Methode unterscheidet sich von object.__repr__() dadurch, dass von __str__() kein gültiger Python-Ausdruck erwartet wird: Eine praktischere oder prägnantere Darstellung kann verwendet werden.

Die Standardimplementierung des eingebauten Typs object ruft object.__repr__() auf.

object.__bytes__(self)

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

object.__format__(self, format_spec)

Wird von der eingebauten Funktion format() und damit von der Auswertung von formatierten Zeichenkettenliteralen und der Methode str.format() aufgerufen, um eine „formatierte“ Zeichenkettenrepräsentation eines Objekts zu erzeugen. Das Argument format_spec ist eine Zeichenkette, die eine Beschreibung der gewünschten Formatierungsoptionen enthält. Die Interpretation des Arguments format_spec obliegt dem Typ, der __format__() implementiert. Die meisten Klassen werden jedoch entweder die Formatierung an einen der eingebauten Typen delegieren oder eine ähnliche Formatierungsoptionssyntax verwenden.

Siehe Format Specification Mini-Language für eine Beschreibung der Standardformatierungssyntax.

Der Rückgabewert muss ein Zeichenkettenobjekt sein.

Die Standardimplementierung der Klasse object sollte eine leere format_spec Zeichenkette erhalten. Sie delegiert an __str__().

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

Geändert in Version 3.7: object.__format__(x, '') ist nun äquivalent zu str(x) statt zu 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 Entsprechung zwischen Operatorsymbolen und Methodennamen ist 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 Rich Comparison-Methode kann das Singleton NotImplemented zurückgeben, wenn sie die Operation für ein gegebenes Paar von Argumenten nicht implementiert. Konventionsgemäß werden False und True für einen erfolgreichen Vergleich zurückgegeben. Diese Methoden können jedoch jeden Wert zurückgeben, sodass, wenn der Vergleichsoperator in einem booleschen Kontext verwendet wird (z. B. in der Bedingung einer if-Anweisung), Python bool() auf den Wert anwendet, um zu bestimmen, ob das Ergebnis wahr oder falsch ist.

Standardmäßig implementiert object __eq__() durch die Verwendung von is und gibt NotImplemented im Falle eines falschen Vergleichs zurück: True if x is y else NotImplemented. Für __ne__() delegiert es standardmäßig an __eq__() und invertiert das Ergebnis, es sei denn, es ist NotImplemented. Es gibt keine anderen impliziten Beziehungen zwischen den Vergleichsoperatoren oder Standardimplementierungen; die Wahrheit von (x<y or x==y) impliziert beispielsweise nicht x<=y. Um Ordering-Operationen automatisch aus einer einzelnen Wurzeloperation zu generieren, siehe functools.total_ordering().

Standardmäßig stellt die Klasse object Implementierungen bereit, die mit Wertvergleichen konsistent sind: Gleichheit vergleicht nach Objektidentität und Ordnungsvergleiche lösen einen TypeError aus. Jede Standardmethode kann diese Ergebnisse direkt generieren, kann aber auch NotImplemented zurückgeben.

Siehe den Abschnitt über __hash__() für einige wichtige Hinweise zur Erstellung von hashbaren Objekten, die benutzerdefinierte Vergleichsoperationen unterstützen und als Dictionary-Schlüssel verwendet werden können.

Es gibt keine vertauschten Argumentversionen dieser Methoden (die verwendet werden sollen, wenn das linke Argument die Operation nicht unterstützt, das rechte Argument jedoch schon); stattdessen sind __lt__() und __gt__() gegenseitige Spiegelbilder, __le__() und __ge__() sind gegenseitige Spiegelbilder, und __eq__() und __ne__() sind ihre eigenen Spiegelbilder. Wenn die Operanden unterschiedliche Typen haben und der Typ des rechten Operanden ein direkter oder indirekter Untertyp des Typs des linken Operanden ist, hat die gespiegelte Methode des rechten Operanden Priorität, andernfalls hat die Methode des linken Operanden Priorität. Virtuelles Vererbung wird nicht berücksichtigt.

Wenn keine geeignete Methode einen anderen Wert als NotImplemented zurückgibt, fallen die Operatoren == und != auf is und is not zurück.

object.__hash__(self)

Wird von der eingebauten Funktion hash() und für Operationen auf Mitgliedern von gehashten Sammlungen, einschließlich set, frozenset und dict, aufgerufen. Die Methode __hash__() sollte eine Ganzzahl zurückgeben. Die einzige erforderliche Eigenschaft ist, dass Objekte, die gleich verglichen werden, denselben Hash-Wert haben. Es wird empfohlen, die Hash-Werte der Komponenten des Objekts, die auch beim Vergleich von Objekten eine Rolle spielen, zu mischen, indem sie in ein Tupel gepackt und das Tupel gehasht werden. Beispiel

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

Hinweis

hash() kürzt den von der benutzerdefinierten __hash__()-Methode eines Objekts zurückgegebenen Wert auf die Größe eines Py_ssize_t. Dies sind typischerweise 8 Bytes bei 64-Bit-Builds und 4 Bytes bei 32-Bit-Builds. Wenn die __hash__()-Methode eines Objekts auf Builds mit unterschiedlicher Bitgröße interoperabel sein muss, stellen Sie sicher, dass Sie die Breite auf allen unterstützten Builds überprüfen. Eine einfache Möglichkeit, dies zu tun, ist mit python -c "import sys; print(sys.hash_info.width)".

Wenn eine Klasse keine __eq__()-Methode definiert, sollte sie auch keine __hash__()-Operation definieren; wenn sie __eq__(), aber nicht __hash__() definiert, sind ihre Instanzen nicht als Elemente in hashbaren Sammlungen verwendbar. Wenn eine Klasse veränderliche Objekte definiert und eine __eq__()-Methode implementiert, sollte sie keine __hash__() implementieren, da die Implementierung von hashbaren Sammlungen erfordert, dass der Hash-Wert eines Schlüssels unveränderlich ist (wenn sich der Hash-Wert des Objekts ändert, befindet es sich im falschen Hash-Bucket).

Benutzerdefinierte Klassen haben standardmäßig __eq__()- und __hash__()-Methoden (geerbt von der Klasse object); mit ihnen sind alle Objekte ungleich (außer mit sich selbst) und x.__hash__() gibt einen geeigneten Wert zurück, sodass x == y sowohl impliziert, dass x is y, als auch dass hash(x) == hash(y).

Eine Klasse, die __eq__() überschreibt und keine __hash__() definiert, wird ihre __hash__() implizit auf None setzen. Wenn die __hash__()-Methode einer Klasse None ist, lösen Instanzen der Klasse einen entsprechenden TypeError aus, wenn ein Programm versucht, ihren Hash-Wert abzurufen, und werden auch korrekt als unhashbar identifiziert, wenn isinstance(obj, collections.abc.Hashable) überprüft wird.

Wenn eine Klasse, die __eq__() überschreibt, die Implementierung von __hash__() einer übergeordneten Klasse beibehalten muss, muss dem Interpreter dies 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 ihre eigene __hash__() definiert, die explizit einen TypeError auslöst, würde bei einem Aufruf von isinstance(obj, collections.abc.Hashable) fälschlicherweise als hashbar identifiziert werden.

Hinweis

Standardmäßig werden die __hash__()-Werte von str- und bytes-Objekten mit einem unvorhersehbaren Zufallswert „gesalzen“. Obwohl sie innerhalb eines einzelnen Python-Prozesses konstant bleiben, sind sie zwischen wiederholten Aufrufen von Python nicht vorhersagbar.

Dies dient dem Schutz vor Denial-of-Service-Angriffen, die durch sorgfältig ausgewählte Eingaben verursacht werden und die Worst-Case-Performance einer Dictionary-Einfügung, O(n2) Komplexität, ausnutzen. Siehe http://ocert.org/advisories/ocert-2011-003.html für Details.

Das Ändern von Hash-Werten beeinflusst die Iterationsreihenfolge von Sets. Python hat nie Garantien für diese Reihenfolge gemacht (und sie variiert typischerweise zwischen 32-Bit- und 64-Bit-Builds).

Siehe auch PYTHONHASHSEED.

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

object.__bool__(self)

Wird aufgerufen, um die Wahrheitswertprüfung und die eingebaute Operation bool() zu implementieren; sollte False oder True zurückgeben. Wenn diese Methode nicht definiert ist, wird __len__() aufgerufen, wenn sie definiert ist, und das Objekt wird als wahr betrachtet, wenn sein Ergebnis ungleich Null ist. Wenn eine Klasse weder __len__() noch __bool__() definiert (was für die Klasse object selbst gilt), gelten alle ihre Instanzen als wahr.

3.3.2. Anpassen des Attributzugriffs

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

object.__getattr__(self, name)

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

Beachten Sie, dass, wenn das Attribut über den normalen Mechanismus gefunden wird, __getattr__() nicht aufgerufen wird. (Dies ist eine beabsichtigte Asymmetrie zwischen __getattr__() und __setattr__().) Dies geschieht sowohl aus Effizienzgründen als auch, weil ansonsten __getattr__() keinen Zugriff auf andere Attribute der Instanz hätte. Beachten Sie, dass Sie zumindest für Instanzvariablen die volle Kontrolle übernehmen können, indem Sie keine Werte im Attributwörterbuch der Instanz einfügen (sondern sie stattdessen in einem anderen Objekt einfügen). Siehe die Methode __getattribute__() unten für eine Möglichkeit, tatsächlich die volle Kontrolle über den Attributzugriff zu erhalten.

object.__getattribute__(self, name)

Wird bedingungslos aufgerufen, um Attributzugriffe für Instanzen der Klasse zu implementieren. Wenn die Klasse auch __getattr__() definiert, wird letzteres nicht aufgerufen, es sei denn, __getattribute__() ruft es explizit auf oder löst eine AttributeError aus. 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 immer die Basisklassenmethode mit demselben Namen aufrufen, um auf benötigte Attribute zuzugreifen, z.B. object.__getattribute__(self, name).

Hinweis

Diese Methode kann bei der Suche nach speziellen Methoden, die sich aus der impliziten Invokation über die Sprachsyntax oder eingebaute Funktionen ergeben, immer noch umgangen werden. Siehe Sonderfall-Suche.

Bei bestimmten sensiblen Attributzugriffen wird ein Audit-Ereignis object.__getattr__ mit den Argumenten obj und name ausgelöst.

object.__setattr__(self, name, value)

Wird aufgerufen, wenn eine Attributzuweisung versucht wird. Dies geschieht anstelle des normalen Mechanismus (d.h. Speichern des Werts im Instanzwörterbuch). name ist der Attributname, value ist der zuzuweisende Wert.

Wenn __setattr__() einem Instanzattribut eine Zuweisung vornehmen möchte, sollte es die Basisklassenmethode mit demselben Namen aufrufen, z.B. object.__setattr__(self, name, value).

Bei bestimmten sensiblen Attributzuweisungen wird ein Audit-Ereignis object.__setattr__ mit den Argumenten obj, name, value ausgelöst.

object.__delattr__(self, name)

Ähnlich wie __setattr__(), aber für das Löschen von Attributen anstelle von Zuweisungen. Dies sollte nur implementiert werden, wenn del obj.name für das Objekt sinnvoll ist.

Bei bestimmten sensiblen Attributlöschungen wird ein Audit-Ereignis object.__delattr__ mit den Argumenten obj und name ausgelöst.

object.__dir__(self)

Wird aufgerufen, wenn dir() auf das Objekt angewendet wird. Ein iterierbares Objekt muss zurückgegeben werden. dir() wandelt das zurückgegebene iterierbare Objekt in eine Liste um und sortiert diese.

3.3.2.1. Anpassen des Zugriffs auf Modulattribute

module.__getattr__()
module.__dir__()

Spezielle Namen wie __getattr__ und __dir__ können ebenfalls verwendet werden, um den Zugriff auf Modulattribute anzupassen. Die __getattr__-Funktion auf Modulebene sollte ein Argument akzeptieren, das den Namen eines Attributs ist, und den berechneten Wert zurückgeben oder eine AttributeError auslösen. Wenn ein Attribut auf einem Modulobjekt über die normale Suche, d.h. object.__getattribute__(), nicht gefunden wird, dann wird __getattr__ im __dict__ des Moduls gesucht, bevor eine AttributeError ausgelöst wird. Wenn gefunden, wird sie mit dem Attributnamen aufgerufen und das Ergebnis zurückgegeben.

Die Funktion __dir__ sollte keine Argumente akzeptieren und ein iterierbares Objekt von Zeichenketten zurückgeben, das die auf dem Modul zugänglichen Namen darstellt. Wenn vorhanden, überschreibt diese Funktion die Standard-dir()-Suche auf einem Modul.

module.__class__

Für eine feinere Anpassung des Modulverhaltens (Setzen von Attributen, Eigenschaften usw.) kann das Attribut __class__ eines Modulobjekts auf eine Unterklasse von types.ModuleType gesetzt werden. 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

Hinweis

Das Definieren von Modul __getattr__ und das Setzen von Modul __class__ wirkt sich nur auf Lookups aus, die über die Attributzugriffssyntax erfolgen – direkter Zugriff auf die globalen Variablen des Moduls (sei es durch Code innerhalb des Moduls oder über eine Referenz auf das globale Wörterbuch des Moduls) ist davon unberührt.

Geändert in Version 3.5: Das Modulattribut __class__ ist jetzt beschreibbar.

Hinzugefügt in Version 3.7: Modulattribute __getattr__ und __dir__.

Siehe auch

PEP 562 – Module __getattr__ und __dir__

Beschreibt die Funktionen __getattr__ und __dir__ in Modulen.

3.3.2.2. Implementieren von Deskriptoren

Die folgenden Methoden gelten nur, wenn eine Instanz der Klasse, die die Methode enthält (eine sogenannte *Deskriptorklasse*), in einer *Besitzerklasse* (die Deskriptorklasse muss sich entweder im Klassenwörterbuch des Besitzers oder im Klassenwörterbuch eines seiner Elternteile befinden) erscheint. In den folgenden Beispielen bezieht sich "das Attribut" auf das Attribut, dessen Name der Schlüssel der Eigenschaft im __dict__ der Besitzerklasse ist. Die Klasse object selbst implementiert kein dieser Protokolle.

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

Wird aufgerufen, um das Attribut der Besitzerklasse (Klassenattributzugriff) oder einer Instanz dieser Klasse (Instanzattributzugriff) zu erhalten. Das optionale Argument owner ist die Besitzerklasse, während instance die Instanz ist, über die auf das Attribut zugegriffen wurde, oder None, wenn auf das Attribut über den owner zugegriffen wurde.

Diese Methode sollte den berechneten Attributwert zurückgeben oder eine AttributeError Ausnahme auslösen.

PEP 252 gibt vor, dass __get__() mit einem oder zwei Argumenten aufrufbar ist. Pythons eigene eingebaute Deskriptoren unterstützen diese Spezifikation; es ist jedoch wahrscheinlich, dass einige Tools von Drittanbietern Deskriptoren haben, die beide Argumente benötigen. Pythons eigene Implementierung von __getattribute__() übergibt immer beide Argumente, ob sie benötigt werden oder nicht.

object.__set__(self, instance, value)

Wird aufgerufen, um das Attribut einer Instanz instance der Besitzerklasse auf einen neuen Wert value zu setzen.

Beachten Sie, dass das Hinzufügen von __set__() oder __delete__() die Art des Deskriptors in einen "Daten-Deskriptor" ändert. Weitere Details finden Sie unter Aufrufen von Deskriptoren.

object.__delete__(self, instance)

Wird aufgerufen, um das Attribut einer Instanz instance der Besitzerklasse zu löschen.

Instanzen von Deskriptoren können auch das Attribut __objclass__ haben

object.__objclass__

Das Attribut __objclass__ wird vom inspect-Modul interpretiert als Angabe der Klasse, in der dieses Objekt definiert wurde (eine entsprechende Einstellung kann die Laufzeit-Introspektion von dynamischen Klassenattributen unterstützen). Für aufrufbare Objekte kann es darauf hinweisen, dass eine Instanz des gegebenen Typs (oder eine Unterklasse) als erstes Positionsargument erwartet oder erforderlich ist (z.B. setzt CPython dieses Attribut für ungebundene Methoden, die in C implementiert sind).

3.3.2.3. Aufrufen von Deskriptoren

Im Allgemeinen ist ein Deskriptor ein Objektattribut mit "Bindungsverhalten", dessen Attributzugriff durch Methoden im Deskriptorprotokoll überschrieben wurde: __get__(), __set__() und __delete__(). Wenn eine dieser Methoden für ein Objekt definiert ist, wird es als Deskriptor bezeichnet.

Das Standardverhalten für den Attributzugriff besteht darin, das Attribut aus dem Wörterbuch eines Objekts zu holen, zu setzen oder zu löschen. Zum Beispiel hat a.x eine Suchkette, die mit a.__dict__['x'] beginnt, dann type(a).__dict__['x'] und weiter durch die Basisklassen von type(a) (ohne Metaklassen) fortfährt.

Wenn der nachgeschlagene Wert jedoch ein Objekt ist, das eine der Deskriptormethoden definiert, kann Python das Standardverhalten überschreiben und stattdessen die Deskriptormethode aufrufen. Wo dies in der Vorrangkette geschieht, hängt davon ab, welche Deskriptormethoden definiert wurden und wie sie aufgerufen wurden.

Der Ausgangspunkt für die Deskriptorinvokation ist eine Bindung, a.x. Wie die Argumente zusammengestellt werden, hängt von a ab

Direkter Aufruf

Der einfachste und seltenste Aufruf ist, wenn Benutzercode eine Deskriptormethode direkt aufruft: x.__get__(a).

Instanzbindung

Wenn an eine Objektinstanz gebunden wird, wird a.x in den Aufruf transformiert: type(a).__dict__['x'].__get__(a, type(a)).

Klassenbindung

Wenn an eine Klasse gebunden wird, wird A.x in den Aufruf transformiert: A.__dict__['x'].__get__(None, A).

Super-Bindung

Eine punktierte Suche wie super(A, a).x durchsucht a.__class__.__mro__ nach einer Basisklasse B nach A und gibt dann B.__dict__['x'].__get__(a, A) zurück. Wenn es sich nicht um einen Deskriptor handelt, wird x unverändert zurückgegeben.

Für Instanzbindungen hängt die Priorität der Deskriptorinvokation davon ab, welche Deskriptormethoden definiert sind. Ein Deskriptor kann jede Kombination von __get__(), __set__() und __delete__() definieren. Wenn es __get__() nicht definiert, gibt der Zugriff auf das Attribut das Deskriptorobjekt selbst zurück, es sei denn, es gibt einen Wert im Instanzwörterbuch des Objekts. Wenn der Deskriptor __set__() und/oder __delete__() definiert, ist es ein Daten-Deskriptor; wenn es keines davon definiert, ist es ein Nicht-Daten-Deskriptor. Normalerweise definieren Daten-Deskriptoren sowohl __get__() als auch __set__(), während Nicht-Daten-Deskriptoren nur die __get__()-Methode haben. Daten-Deskriptoren mit definierten __get__() und __set__() (und/oder __delete__()) überschreiben immer eine Neudefinition in einem Instanzwörterbuch. Im Gegensatz dazu können Nicht-Daten-Deskriptoren durch Instanzen überschrieben werden.

Python-Methoden (einschließlich der mit @staticmethod und @classmethod dekorierten) werden als Nicht-Daten-Deskriptoren implementiert. Daher können Instanzen Methoden neu definieren und überschreiben. Dies ermöglicht es einzelnen Instanzen, Verhaltensweisen zu erwerben, die sich von anderen Instanzen derselben Klasse unterscheiden.

Die Funktion property() wird als Daten-Deskriptor implementiert. Daher können Instanzen das Verhalten einer Eigenschaft nicht überschreiben.

3.3.2.4. __slots__

__slots__ erlauben uns, explizit Datenmember (wie Eigenschaften) zu deklarieren und die Erstellung von __dict__ und __weakref__ zu verweigern (es sei denn, sie sind explizit in __slots__ deklariert oder in einem Elternteil verfügbar).

Der Platz, der im Vergleich zur Verwendung von __dict__ gespart wird, kann erheblich sein. Die Geschwindigkeit der Attributsuche kann ebenfalls erheblich verbessert werden.

object.__slots__

Diese Klassenvariable kann einem String, einem iterierbaren Objekt oder einer Sequenz von Strings mit Variablennamen zugewiesen werden, die von Instanzen verwendet werden. __slots__ reserviert Speicher für die deklarierten Variablen und verhindert die automatische Erstellung von __dict__ und __weakref__ für jede Instanz.

Hinweise zur Verwendung von __slots__

  • Beim Erben von einer Klasse ohne __slots__ sind die Attribute __dict__ und __weakref__ der Instanzen immer zugänglich.

  • Ohne eine __dict__-Variable können Instanzen keine neuen Variablen zugewiesen werden, die nicht in der __slots__-Definition aufgeführt sind. Versuche, einer nicht aufgelisteten Variablennamen zuzuweisen, lösen eine AttributeError aus. Wenn eine dynamische Zuweisung neuer Variablen gewünscht ist, fügen Sie '__dict__' zur Sequenz von Strings 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 Unterstützung für schwache Referenzen benötigt wird, fügen Sie '__weakref__' zur Sequenz von Strings in der __slots__-Deklaration hinzu.

  • __slots__ werden auf Klassenebene implementiert, indem Deskriptoren für jeden Variablennamen erstellt werden. Daher können Klassenattribute nicht verwendet werden, um Standardwerte für Instanzvariablen festzulegen, die von __slots__ definiert wurden; andernfalls würde das Klassenattribut die Deskriptorzuweisung überschreiben.

  • Die Aktion einer __slots__-Deklaration beschränkt sich nicht auf die Klasse, in der sie definiert ist. In Elternklassen deklarierte __slots__ sind in Kindklassen verfügbar. Instanzen einer Kindunterklasse erhalten jedoch ein __dict__ und __weakref__, es sei denn, die Unterklasse definiert ebenfalls __slots__ (die nur Namen für *zusätzliche* Slots enthalten sollte).

  • Wenn eine Klasse einen Slot definiert, der bereits in einer Basisklasse definiert ist, ist die Instanzvariable, die vom Basisklassenslot definiert wird, unzugänglich (außer durch direkte Abfrage ihres Deskriptors von der Basisklasse). Dies macht die Bedeutung des Programms undefiniert. In Zukunft kann eine Prüfung hinzugefügt werden, um dies zu verhindern.

  • Eine TypeError wird ausgelöst, wenn nicht-leere __slots__ für eine Klasse definiert werden, die von einem "variable-length" eingebauten Typ wie int, bytes und tuple abgeleitet ist.

  • Jede nicht-String-iterierbare kann __slots__ zugewiesen werden.

  • Wenn ein Wörterbuch zur Zuweisung von __slots__ verwendet wird, werden die Wörterbuchschlüssel als Slotnamen verwendet. Die Werte des Wörterbuchs können zur Bereitstellung von Dokumentationsstrings pro Attribut verwendet werden, die von inspect.getdoc() erkannt und in der Ausgabe von help() angezeigt werden.

  • __class__-Zuweisung funktioniert nur, wenn beide Klassen dieselben __slots__ haben.

  • Es kann Mehrfachvererbung mit mehreren Slot-basierten Elternklassen verwendet werden, aber nur ein Elternteil darf Attribute haben, die durch Slots erstellt wurden (die anderen Basen müssen leere Slot-Layouts haben) – Verstöße lösen eine TypeError aus.

  • Wenn ein Iterator für __slots__ verwendet wird, wird für jeden Wert des Iterators ein Deskriptor erstellt. Das Attribut __slots__ wird jedoch ein leerer Iterator sein.

3.3.3. Anpassen der Klassenerstellung

Immer wenn eine Klasse von einer anderen Klasse erbt, wird __init_subclass__() auf der Elternklasse aufgerufen. Auf diese Weise ist es möglich, Klassen zu schreiben, die das Verhalten von Unterklassen ändern. Dies steht in engem Zusammenhang mit Klassendekoratoren, aber während Klassendekoratoren nur die spezifische Klasse beeinflussen, auf die sie angewendet werden, gilt __init_subclass__ ausschließlich für zukünftige Unterklassen der Klasse, die die Methode definiert.

classmethod object.__init_subclass__(cls)

Diese Methode wird aufgerufen, wenn die enthaltende Klasse unterklassenbildet wird. cls ist dann die neue Unterklasse. Wenn als normale Instanzmethode definiert, wird diese Methode implizit in eine Klassenmethode umgewandelt.

Schlüsselwortargumente, die an eine neue Klasse übergeben werden, werden an die __init_subclass__ der Elternklasse übergeben. Zur Kompatibilität mit anderen Klassen, die __init_subclass__ verwenden, sollte man die benötigten Schlüsselwortargumente entnehmen und die anderen an die Basisklasse weitergeben, wie z.B.

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__ tut nichts, löst aber einen Fehler aus, wenn sie mit Argumenten aufgerufen wird.

Hinweis

Der Metaklassenhinweis metaclass wird vom Rest der Typen-Maschinerie verarbeitet und niemals an __init_subclass__-Implementierungen übergeben. Die tatsächliche Metaklasse (anstatt des expliziten Hinweises) kann als type(cls) abgerufen werden.

Hinzugefügt in Version 3.6.

Wenn eine Klasse erstellt wird, durchsucht type.__new__() die Klassenvariablen und ruft die mit einem __set_name__-Hook auf.

object.__set_name__(self, owner, name)

Wird automatisch aufgerufen, wenn die Besitzerklasse owner erstellt wird. Das Objekt wurde in dieser Klasse unter name zugewiesen.

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')

Wenn die Klassenvariable nach der Klassenerstellung zugewiesen wird, 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

Siehe Erstellen des Klassenobjekts für weitere Details.

Hinzugefügt in Version 3.6.

3.3.3.1. Metaklassen

Standardmäßig werden Klassen mit type() konstruiert. 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 kann angepasst werden, indem das Schlüsselwortargument metaclass in der Klassendefinitionszeile übergeben wird oder indem von einer vorhandenen Klasse geerbt wird, die ein solches Argument enthielt. 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 anderen Schlüsselwortargumente, die in der Klassendefinition angegeben sind, werden an alle unten beschriebenen Metaklassenoperationen weitergegeben.

Wenn eine Klassendefinition ausgeführt wird, geschehen folgende Schritte:

  • MRO-Einträge werden aufgelöst;

  • die entsprechende Metaklasse wird bestimmt;

  • der Klassen-Namensraum wird vorbereitet;

  • der Klassenkörper wird ausgeführt;

  • das Klassenobjekt wird erstellt.

3.3.3.2. Auflösen von MRO-Einträgen

object.__mro_entries__(self, bases)

Wenn eine Basis, die in einer Klassendefinition vorkommt, keine Instanz von type ist, dann wird eine __mro_entries__()-Methode auf der Basis gesucht. Wenn eine __mro_entries__()-Methode gefunden wird, wird die Basis durch das Ergebnis eines Aufrufs von __mro_entries__() bei der Erstellung der Klasse ersetzt. Die Methode wird mit dem ursprünglichen Basen-Tupel, das dem Parameter bases übergeben wurde, aufgerufen und muss ein Tupel von Klassen zurückgeben, die anstelle der Basis verwendet werden. Das zurückgegebene Tupel kann leer sein: in diesen Fällen wird die ursprüngliche Basis ignoriert.

Siehe auch

types.resolve_bases()

Löst dynamisch Basen auf, die keine Instanzen von type sind.

types.get_original_bases()

Ruft die "Original-Basen" einer Klasse ab, bevor diese durch __mro_entries__() modifiziert wurden.

PEP 560

Kernunterstützung für das Modul Typen und generische Typen.

3.3.3.3. Bestimmen der geeigneten Metaklasse

Die geeignete Metaklasse für eine Klassendefinition wird wie folgt bestimmt:

  • Wenn keine Basisklassen und keine explizite Metaklasse angegeben sind, wird type() verwendet.

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

  • Wenn eine Instanz von type() als explizite Metaklasse angegeben wird oder Basisklassen definiert sind, wird die am weitesten abgeleitete Metaklasse verwendet.

Die am weitesten abgeleitete Metaklasse wird aus der explizit angegebenen Metaklasse (falls vorhanden) und den Metaklassen (d.h. type(cls)) aller angegebenen Basisklassen ausgewählt. Die am weitesten abgeleitete Metaklasse ist diejenige, die ein Untertyp aller dieser Kandidaten-Metaklassen ist. Wenn keine der Kandidaten-Metaklassen dieses Kriterium erfüllt, schlägt die Klassendefinition mit TypeError fehl.

3.3.3.4. Vorbereitung des Klassen-Namespace

Sobald die geeignete Metaklasse identifiziert wurde, wird der Klassen-Namespace vorbereitet. Wenn die Metaklasse ein Attribut __prepare__ hat, wird sie als namespace = metaclass.__prepare__(name, bases, **kwds) aufgerufen (wobei die zusätzlichen Schlüsselwortargumente, falls vorhanden, aus der Klassendefinition stammen). Die Methode __prepare__ sollte als classmethod implementiert werden. Der von __prepare__ zurückgegebene Namespace wird an __new__ übergeben, aber wenn das endgültige Klassenobjekt erstellt wird, wird der Namespace in ein neues dict kopiert.

Wenn die Metaklasse kein Attribut __prepare__ hat, wird der Klassen-Namespace als leeres geordnetes Mapping initialisiert.

Siehe auch

PEP 3115 - Metaklassen in Python 3000

Führte den Namespace-Hook __prepare__ ein.

3.3.3.5. Ausführung des Klassenkörpers

Der Klassenkörper wird (ungefähr) als exec(body, globals(), namespace) ausgeführt. Der Hauptunterschied zu einem normalen Aufruf von exec() besteht darin, dass die lexikalische Geltung (scoping) es dem Klassenkörper (einschließlich aller Methoden) ermöglicht, auf Namen aus dem aktuellen und äußeren Geltungsbereich zuzugreifen, wenn die Klassendefinition innerhalb einer Funktion erfolgt.

Auch wenn die Klassendefinition innerhalb einer Funktion erfolgt, können innerhalb der Klasse definierte Methoden Namen, die im Klassenbereich definiert sind, immer noch nicht sehen. Klassenvariablen müssen über den ersten Parameter von Instanz- oder Klassenmethoden oder über die implizite lexikalisch gültige Referenz __class__, die im nächsten Abschnitt beschrieben wird, aufgerufen werden.

3.3.3.6. Erstellung des Klassenobjekts

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

Dieses Klassenobjekt ist dasjenige, auf das sich die Null-Argument-Form von super() beziehen wird. __class__ ist eine implizite Closure-Referenz, die vom Compiler erstellt wird, wenn Methoden im Klassenkörper auf entweder __class__ oder super verweisen. Dies ermöglicht es der Null-Argument-Form von super(), die definierte Klasse korrekt zu identifizieren, basierend auf der lexikalischen Geltung, während die Klasse oder Instanz, die für den aktuellen Aufruf verwendet wurde, basierend auf dem ersten an die Methode übergebenen Argument identifiziert wird.

CPython-Implementierungsdetail: In CPython 3.6 und neuer wird die Zelle __class__ als Eintrag __classcell__ im Klassen-Namespace an die Metaklasse übergeben. Falls vorhanden, muss dies an den Aufruf type.__new__ weitergegeben werden, damit die Klasse korrekt initialisiert wird. Wenn dies nicht geschieht, führt dies in Python 3.8 zu einem RuntimeError.

Wenn die Standard-Metaklasse type oder eine Metaklasse, die letztendlich type.__new__ aufruft, verwendet wird, 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 Methode __set_name__() definieren;

  2. Diese Methoden __set_name__ werden mit der definierten Klasse und dem zugewiesenen Namen dieses speziellen Attributs aufgerufen;

  3. Der Hook __init_subclass__() wird auf dem direkten Elternteil der neuen Klasse in ihrer Methodenauflösungsreihenfolge aufgerufen.

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

Wenn eine neue Klasse von type.__new__ erstellt wird, wird das als Namespace-Parameter bereitgestellte Objekt in ein neues geordnetes Mapping kopiert und das ursprüngliche Objekt verworfen. Die neue Kopie wird in einen schreibgeschützten Proxy eingewickelt, der zum Attribut __dict__ des Klassenobjekts wird.

Siehe auch

PEP 3135 - Neues super

Beschreibt die implizite Closure-Referenz __class__.

3.3.3.7. Verwendungen für Metaklassen

Die potenziellen Verwendungen für Metaklassen sind grenzenlos. Einige untersuchte Ideen sind Enums, Logging, Schnittstellenprüfung, automatische Delegation, automatische Erstellung von Eigenschaften, Proxys, Frameworks und automatische Ressourcensperrung/-synchronisation.

3.3.4. Anpassen von Instanz- und Unterklassenprüfungen

Die folgenden Methoden werden verwendet, um das Standardverhalten der eingebauten Funktionen isinstance() und issubclass() zu überschreiben.

Insbesondere implementiert die Metaklasse abc.ABCMeta diese Methoden, um die Hinzufügung von abstrakten Basisklassen (ABCs) als „virtuelle Basisklassen“ zu jeder Klasse oder jedem Typ (einschließlich integrierter Typen), einschließlich anderer ABCs, zu ermöglichen.

type.__instancecheck__(self, instance)

Gibt true zurück, wenn instance als (direkte oder indirekte) Instanz von class betrachtet werden soll. Wenn definiert, wird es zur Implementierung von isinstance(instance, class) aufgerufen.

type.__subclasscheck__(self, subclass)

Gibt true zurück, wenn subclass als (direkte oder indirekte) Unterklasse von class betrachtet werden soll. Wenn definiert, wird es zur Implementierung von issubclass(subclass, class) aufgerufen.

Beachten Sie, dass diese Methoden auf dem Typ (Metaklasse) einer Klasse nachgeschlagen werden. Sie können nicht als Klassenmethoden in der eigentlichen Klasse definiert werden. Dies stimmt mit dem Nachschlagen von Sonder-Methoden überein, die auf Instanzen aufgerufen werden, nur dass in diesem Fall die Instanz selbst eine Klasse ist.

Siehe auch

PEP 3119 - Einführung von abstrakten Basisklassen

Enthält die Spezifikation für die Anpassung des Verhaltens von isinstance() und issubclass() durch __instancecheck__() und __subclasscheck__(), mit der Begründung für diese Funktionalität im Kontext der Hinzufügung von abstrakten Basisklassen (siehe Modul abc) zur Sprache.

3.3.5. Emulieren generischer Typen

Bei der Verwendung von Typ-Annotationen ist es oft nützlich, einen generischen Typ mithilfe der Square-Bracket-Notation von Python 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-Hints

Einführung des Python-Frameworks für Typ-Annotationen.

Generische Alias-Typen

Dokumentation für Objekte, die parametrisierte generische Klassen darstellen.

Generics, selbst definierte Generics und typing.Generic

Dokumentation zur Implementierung von generischen Klassen, die zur Laufzeit parametrisiert und von statischen Typ-Prüfern verstanden werden können.

Eine Klasse kann im Allgemeinen nur 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 durch die in key gefundenen Typargumente darstellt.

Wenn __class_getitem__() auf einer Klasse definiert ist, ist sie automatisch eine Klassenmethode. Daher besteht keine Notwendigkeit, sie mit @classmethod zu dekorieren, wenn sie definiert wird.

3.3.5.1. Der Zweck von __class_getitem__

Der Zweck von __class_getitem__() ist die Laufzeitparametrisierung von generischen Standardbibliotheksklassen, um Typ-Hints für diese Klassen leichter anwenden zu können.

Um benutzerdefinierte generische Klassen zu implementieren, die zur Laufzeit parametrisiert und von statischen Typ-Prüfern verstanden werden können, sollten Benutzer entweder von einer Standardbibliotheksklasse erben, die __class_getitem__() bereits implementiert, oder von typing.Generic erben, die eine eigene Implementierung von __class_getitem__() hat.

Benutzerdefinierte Implementierungen von __class_getitem__() auf Klassen, die außerhalb der Standardbibliothek definiert sind, werden möglicherweise nicht von Drittanbieter-Typ-Prüfern wie mypy verstanden. Die Verwendung von __class_getitem__() auf beliebigen Klassen für andere Zwecke als Typ-Hints wird nicht empfohlen.

3.3.5.2. __class_getitem__ versus __getitem__

Normalerweise ruft die Subscription eines Objekts mit eckigen Klammern die Instanzmethode __getitem__() auf, die auf der Klasse des Objekts definiert ist. Wenn das zu abonnierende Objekt jedoch selbst eine Klasse ist, kann stattdessen die Klassenmethode __class_getitem__() aufgerufen werden. __class_getitem__() sollte ein GenericAlias-Objekt zurückgeben, wenn es korrekt definiert ist.

Angesichts des Ausdrucks obj[x] folgt der Python-Interpreter ungefähr dem folgenden Prozess, 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 ihre Metaklasse bezeichnet, und die meisten Klassen haben die Klasse type als ihre 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 eine benutzerdefinierte Metaklasse hat, die __getitem__() definiert, kann die Subscription der Klasse zu einem anderen Verhalten führen. Ein Beispiel dafü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 typing-Modul und generische Typen

Einführung von __class_getitem__() und Beschreibung, wann eine Subscription dazu führt, dass __class_getitem__() anstelle von __getitem__() aufgerufen wird.

3.3.6. Emulieren von aufrufbaren Objekten

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

Wird aufgerufen, wenn die Instanz wie eine Funktion „aufgerufen“ wird; wenn diese Methode definiert ist, wird x(arg1, arg2, ...) ungefähr zu type(x).__call__(x, arg1, ...).

3.3.7. Emulieren von Container-Objekten

Die folgenden Methoden können definiert werden, um Container-Objekte zu implementieren. Keine davon wird von der Klasse object selbst bereitgestellt. Container sind normalerweise Sequenzen (wie Listen oder Tupel) oder Mappings (wie Dictionaries), können aber auch andere Container darstellen. Die erste Gruppe von Methoden wird verwendet, um entweder eine Sequenz oder ein Mapping zu emulieren; der Unterschied besteht darin, dass für eine Sequenz die erlaubten Schlüssel die ganzen Zahlen k sind, für die 0 <= k < N gilt, wobei N die Länge der Sequenz ist, oder slice-Objekte, die einen Bereich von Elementen definieren. Es wird auch empfohlen, dass Mappings die Methoden keys(), values(), items(), get(), clear(), setdefault(), pop(), popitem(), copy() und update() bereitstellen, die sich ähnlich wie die für die Standard- Dictionary-Objekte von Python verhalten. Das Modul collections.abc stellt eine MutableMapping abstrakte Basisklasse zur Verfügung, um diese Methoden aus einem Basissatz von __getitem__(), __setitem__(), __delitem__() und keys() zu erstellen.

Mutable Sequenzen sollten die Methoden append(), clear(), count(), extend(), index(), insert(), pop(), remove() und reverse() bereitstellen, wie Python-Standard- Listen-Objekte. Schließlich sollten Sequenztypen Addition (d. h. Verkettung) und Multiplikation (d. h. Wiederholung) durch Definition der unten beschriebenen Methoden __add__(), __radd__(), __iadd__(), __mul__(), __rmul__() und __imul__() implementieren; sie sollten keine anderen numerischen Operatoren definieren.

Es wird empfohlen, dass sowohl Mappings als auch Sequenzen die Methode __contains__() implementieren, um eine effiziente Nutzung des in-Operators zu ermöglichen; für Mappings sollte in die Schlüssel des Mappings durchsuchen; für Sequenzen sollte es die Werte durchsuchen. Weiterhin wird empfohlen, dass sowohl Mappings als auch Sequenzen die Methode __iter__() implementieren, um eine effiziente Iteration durch den Container zu ermöglichen; für Mappings sollte __iter__() die Schlüssel des Objekts durchlaufen; für Sequenzen sollte es die Werte durchlaufen.

object.__len__(self)

Wird aufgerufen, um die eingebaute Funktion len() zu implementieren. Sollte die Länge des Objekts zurückgeben, eine Ganzzahl >= 0. Ein Objekt, das keine Methode __bool__() definiert und dessen Methode __len__() null zurückgibt, wird in einem booleschen Kontext als falsch betrachtet.

CPython-Implementierungsdetail: In CPython muss die Länge höchstens sys.maxsize betragen. Wenn die Länge größer als sys.maxsize ist, können einige Funktionen (wie len()) einen OverflowError auslösen. Um die Auslösung eines OverflowError durch boolesche Wertprüfung zu vermeiden, muss ein Objekt eine Methode __bool__() definieren.

object.__length_hint__(self)

Wird aufgerufen, um operator.length_hint() zu implementieren. Soll eine geschätzte Länge für das Objekt zurückgeben (die größer oder kleiner als die tatsächliche Länge sein kann). Die Länge muss eine Ganzzahl >= 0 sein. Der Rückgabewert kann auch NotImplemented sein, was genauso behandelt wird, als ob die Methode __length_hint__ gar nicht existieren würde. Diese Methode dient ausschließlich der Optimierung und ist für die Korrektheit niemals erforderlich.

Hinzugefügt in Version 3.4.

Hinweis

Das Slicing erfolgt ausschließlich mit den folgenden drei Methoden. Ein Aufruf wie

a[1:2] = b

wird übersetzt zu

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

und so weiter. Fehlende Slice-Elemente werden immer mit None gefüllt.

object.__getitem__(self, key)

Wird aufgerufen, um die Auswertung von self[key] zu implementieren. Für Sequenz-Typen sollten die akzeptierten Schlüssel Ganzzahlen sein. Optional können sie auch slice-Objekte unterstützen. Negative Indexunterstützung ist ebenfalls optional. Wenn key von einem unangemessenen Typ ist, kann TypeError ausgelöst werden; wenn key ein Wert außerhalb der Menge der Indizes für die Sequenz ist (nach jeder Sonderinterpretation negativer Werte), sollte IndexError ausgelöst werden. Für Mapping-Typen sollte KeyError ausgelöst werden, wenn key fehlt (nicht im Container vorhanden ist).

Hinweis

for Schleifen erwarten, dass für ungültige Indizes ein IndexError ausgelöst wird, um die korrekte Erkennung des Endes der Sequenz zu ermöglichen.

Hinweis

Beim Subskription einer Klasse kann die spezielle Klassenmethode __class_getitem__() anstelle von __getitem__() aufgerufen werden. Weitere Einzelheiten finden Sie unter __class_getitem__ im Vergleich zu __getitem__.

object.__setitem__(self, key, value)

Wird aufgerufen, um Zuweisungen zu self[key] zu implementieren. Gleicher Hinweis wie für __getitem__(). Dies sollte nur für Mappings implementiert werden, wenn die Objekte Änderungen an den Werten für Schlüssel unterstützen oder neue Schlüssel hinzugefügt werden können, oder für Sequenzen, wenn Elemente ersetzt werden können. Für unzulässige key-Werte sollten dieselben Ausnahmen ausgelöst werden wie für die Methode __getitem__().

object.__delitem__(self, key)

Wird aufgerufen, um die Löschung von self[key] zu implementieren. Gleicher Hinweis wie für __getitem__(). Dies sollte nur für Mappings implementiert werden, wenn die Objekte das Entfernen von Schlüsseln unterstützen, oder für Sequenzen, wenn Elemente aus der Sequenz entfernt werden können. Für unzulässige key-Werte sollten dieselben Ausnahmen ausgelöst werden wie für die Methode __getitem__().

object.__missing__(self, key)

Wird von dict.__getitem__() aufgerufen, um self[key] für dict-Subklassen zu implementieren, wenn der Schlüssel nicht im Dictionary vorhanden ist.

object.__iter__(self)

Diese Methode wird aufgerufen, wenn ein Iterator für einen Container benötigt wird. Diese Methode sollte ein neues Iteratorobjekt zurückgeben, das über alle Objekte im Container iterieren kann. Für Mappings sollte es über die Schlüssel des Containers iterieren.

object.__reversed__(self)

Wird (falls vorhanden) von der integrierten Funktion reversed() aufgerufen, um die umgekehrte Iteration zu implementieren. Sie sollte ein neues Iteratorobjekt zurückgeben, das über alle Objekte im Container in umgekehrter Reihenfolge iteriert.

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

Die Membership-Test-Operatoren (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, die auch nicht erfordert, dass das Objekt iterierbar ist.

object.__contains__(self, item)

Wird aufgerufen, um Membership-Test-Operatoren zu implementieren. Sollte `true` zurückgeben, wenn item in self ist, andernfalls `false`. Für Mapping-Objekte sollte dies die Schlüssel des Mappings berücksichtigen, nicht die Werte oder Schlüssel-Element-Paare.

Für Objekte, die __contains__() nicht definieren, versucht der Membership-Test zuerst eine Iteration über __iter__() und dann das alte Sequenz-Iterationsprotokoll über __getitem__(), siehe diesen Abschnitt in der Sprachreferenz.

3.3.8. Emulieren numerischer Typen

Die folgenden Methoden können definiert werden, um numerische Objekte zu emulieren. Methoden, die Operationen entsprechen, die von der implementierten Zahl 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)

Diese Methoden werden aufgerufen, um die binären arithmetischen Operationen (+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |) zu implementieren. Zum Beispiel wird zur Auswertung des Ausdrucks x + y, wobei x eine Instanz einer Klasse ist, die eine Methode __add__() hat, type(x).__add__(x, y) aufgerufen. Die Methode __divmod__() sollte dem Gebrauch von __floordiv__() und __mod__() entsprechen; sie sollte nicht mit __truediv__() zusammenhängen. Beachten Sie, dass __pow__() einen optionalen dritten Parameter akzeptieren sollte, wenn die dreistellige Version der integrierten Funktion pow() unterstützt werden soll.

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)

Diese Methoden werden aufgerufen, um die binären arithmetischen Operationen (+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |) mit reflektierten (vertauschten) Operanden zu implementieren. Diese Funktionen werden nur aufgerufen, wenn die Operanden unterschiedliche Typen haben, wenn der linke Operand die entsprechende Operation nicht unterstützt [3] oder wenn die Klasse des rechten Operanden von der Klasse des linken Operanden abgeleitet ist [4]. Zum Beispiel wird zur Auswertung des Ausdrucks x - y, wobei y eine Instanz einer Klasse ist, die eine Methode __rsub__() hat, type(y).__rsub__(y, x) aufgerufen, wenn type(x).__sub__(x, y) NotImplemented zurückgibt oder type(y) eine Unterklasse von type(x) ist [5].

Beachten Sie, dass __rpow__() einen optionalen dritten Parameter akzeptieren sollte, wenn die dreistellige Version der integrierten Funktion pow() unterstützt werden soll.

Geändert in Version 3.14: Die dreistellige Funktion pow() versucht nun, __rpow__() aufzurufen, falls erforderlich. Zuvor wurde sie nur in der zweistelligen Funktion pow() und im binären Potenzoperator aufgerufen.

Hinweis

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 aufgerufen, bevor die nicht-reflektierte Methode des linken Operanden aufgerufen wird. 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 augmentierten arithmetischen Zuweisungen zu implementieren (+=, -=, *=, @=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=). Diese Methoden sollten versuchen, die Operation direkt durchzuführen (indem self modifiziert wird) und das Ergebnis zurückzugeben (was self sein kann, aber nicht muss). Wenn eine bestimmte Methode nicht definiert ist oder wenn diese Methode NotImplemented zurückgibt, greift die augmentierte Zuweisung auf die normalen Methoden zurück. Wenn beispielsweise x eine Instanz einer Klasse mit einer __iadd__()-Methode ist, ist x += y äquivalent zu x = x.__iadd__(y). Wenn __iadd__() nicht existiert oder wenn x.__iadd__(y) NotImplemented zurückgibt, werden x.__add__(y) und y.__radd__(x) berücksichtigt, wie bei der Auswertung von x + y. In bestimmten Situationen kann die augmentierte Zuweisung zu unerwarteten Fehlern führen (siehe Warum löst a_tuple[i] += ['item'] eine Ausnahme aus, wenn die Addition funktioniert?), aber dieses Verhalten ist tatsächlich Teil des Datenmodells.

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

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

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

Aufgerufen, um die eingebauten Funktionen complex(), int() und float() zu implementieren. Sollte einen Wert vom entsprechenden Typ zurückgeben.

object.__index__(self)

Aufgerufen, um operator.index() zu implementieren und immer dann, wenn Python benötigt, das numerische Objekt verlustfrei in ein ganzzahliges Objekt zu konvertieren (wie z. B. beim Slicing oder in den eingebauten Funktionen bin(), hex() und oct()). Das Vorhandensein dieser Methode zeigt an, dass das numerische Objekt ein ganzzahliger Typ ist. Muss eine Ganzzahl zurückgeben.

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

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

Aufgerufen, um die eingebaute Funktion round() und die math-Funktionen trunc(), floor() und ceil() zu implementieren. Sofern ndigits nicht an __round__() übergeben wird, sollten alle diese Methoden den auf einen Integral (typischerweise eine int) gekürzten Wert des Objekts zurückgeben.

Geändert in Version 3.14: int() delegiert nicht mehr an die Methode __trunc__().

3.3.9. With Statement Context Managers

Ein Kontextmanager ist ein Objekt, das den Laufzeitkontext definiert, der beim Ausführen einer with-Anweisung eingerichtet werden soll. Der Kontextmanager kümmert sich um den Eintritt in und den Austritt aus dem gewünschten Laufzeitkontext für die Ausführung des Codeblocks. Kontextmanager werden normalerweise über die with-Anweisung aufgerufen (siehe Abschnitt Die with-Anweisung), können aber auch durch direktes Aufrufen ihrer Methoden verwendet werden.

Typische Anwendungsfälle für Kontextmanager sind das Speichern und Wiederherstellen verschiedener Arten von globalem Zustand, das Sperren und Entsperren von Ressourcen, das Schließen geöffneter Dateien usw.

Weitere Informationen zu Kontextmanagern finden Sie unter Context Manager Types. Die Klasse object selbst stellt keine Kontextmanager-Methoden bereit.

object.__enter__(self)

Betritt den Laufzeitkontext, der mit diesem Objekt verbunden ist. Die with-Anweisung bindet den Rückgabewert dieser Methode an das/die Ziel(e), das/die in der as-Klausel der Anweisung angegeben ist/sind, falls vorhanden.

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

Verlässt den Laufzeitkontext, der mit diesem Objekt verbunden ist. Die Parameter beschreiben die Ausnahme, die zum Verlassen des Kontexts geführt hat. Wenn der Kontext ohne Ausnahme verlassen wurde, sind alle drei Argumente None.

Wenn eine Ausnahme übergeben wird und die Methode die Ausnahme unterdrücken möchte (d.h. verhindern, dass sie weitergegeben wird), sollte sie einen wahren Wert zurückgeben. Andernfalls wird die Ausnahme nach dem Verlassen dieser Methode normal verarbeitet.

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

Siehe auch

PEP 343 - Die „with“-Anweisung

Die Spezifikation, der Hintergrund und Beispiele für die Python with-Anweisung.

3.3.10. Anpassen von Positionsargumenten in der Klassenmustererkennung

Wenn ein Klassenname in einem Muster verwendet wird, sind Positionsargumente im Muster standardmäßig nicht erlaubt, d.h. case MyClass(x, y) ist normalerweise ungültig, es sei denn, MyClass unterstützt dies speziell. Um diese Art von Muster verwenden zu können, muss die Klasse ein __match_args__-Attribut definieren.

object.__match_args__

Diese Klassenvariable kann mit einem Tupel von 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üssel verwendet wird. Das Fehlen dieses Attributs entspricht dessen Zuweisung zu ().

Wenn beispielsweise MyClass.__match_args__ gleich ("left", "center", "right") ist, bedeutet dies, dass case MyClass(x, y) äquivalent zu 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; wenn sie größer ist, löst der Musterabgleichsversuch eine TypeError aus.

Hinzugefügt in Version 3.10.

Siehe auch

PEP 634 - Strukturierte Mustererkennung

Die Spezifikation für die Python match-Anweisung.

3.3.11. Emulation von Puffertypen

Das Pufferprotokoll bietet eine Möglichkeit, Python-Objekten effizienten Zugriff auf ein Low-Level-Speicherarray zu ermöglichen. Dieses Protokoll wird von eingebauten Typen wie bytes und memoryview implementiert, und Drittanbieterbibliotheken können zusätzliche Puffertypen definieren.

Obwohl Puffertypen normalerweise in C implementiert werden, ist es auch möglich, das Protokoll in Python zu implementieren.

object.__buffer__(self, flags)

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

object.__release_buffer__(self, buffer)

Wird aufgerufen, wenn ein Puffer nicht mehr benötigt wird. Das Argument buffer ist ein memoryview-Objekt, das zuvor von __buffer__() zurückgegeben wurde. Die Methode muss alle mit dem Puffer verbundenen Ressourcen freigeben. Diese Methode sollte None zurückgeben. Pufferobjekte, die keine Bereinigungsarbeiten durchführen müssen, müssen diese Methode nicht implementieren.

Hinzugefügt in Version 3.12.

Siehe auch

PEP 688 - Zugänglichmachung des Pufferprotokolls in Python

Führt die Python-Methoden __buffer__ und __release_buffer__ ein.

collections.abc.Buffer

ABC für Puffertypen.

3.3.12. Annotationen

Funktionen, Klassen und Module können Annotationen enthalten, die eine Möglichkeit darstellen, Informationen (typischerweise Typ-Hints) mit einem Symbol zu verknüpfen.

object.__annotations__

Dieses Attribut enthält die Annotationen für ein Objekt. Es wird verzögert ausgewertet, sodass der Zugriff auf das Attribut beliebigen Code ausführen und Ausnahmen auslösen kann. Wenn die Auswertung erfolgreich ist, wird das Attribut auf ein Wörterbuch gesetzt, das Variablennamen auf Annotationen abbildet.

Geändert in Version 3.14: Annotationen werden jetzt verzögert ausgewertet.

object.__annotate__(format)

Eine Annotate-Funktion. Gibt ein neues Wörterbuchobjekt zurück, das Attribut-/Parameter-Namen auf ihre Annotationswerte abbildet.

Nimmt einen Formatparameter entgegen, der das Format angibt, in dem Annotationswerte bereitgestellt werden sollen. Es muss ein Mitglied des Enums annotationlib.Format oder eine Ganzzahl mit einem Wert sein, der einem Mitglied des Enums entspricht.

Wenn eine Annotate-Funktion das angeforderte Format nicht unterstützt, muss sie NotImplementedError auslösen. Annotate-Funktionen müssen immer das VALUE-Format unterstützen; sie dürfen keine NotImplementedError() auslösen, wenn sie mit diesem Format aufgerufen werden.

Wenn sie mit dem VALUE-Format aufgerufen wird, kann eine Annotate-Funktion NameError auslösen; sie darf keinen NameError auslösen, wenn sie ein anderes Format anfordert.

Wenn ein Objekt keine Annotationen hat, sollte __annotate__ vorzugsweise auf None gesetzt werden (es kann nicht gelöscht werden), anstatt auf eine Funktion gesetzt zu werden, die ein leeres Wörterbuch zurückgibt.

Hinzugefügt in Version 3.14.

Siehe auch

PEP 649 – Verzögerte Auswertung von Annotationen mittels Deskriptoren

Führt die verzögerte Auswertung von Annotationen und die Funktion __annotate__ ein.

3.3.13. Suche nach speziellen Methoden

Bei benutzerdefinierten Klassen sind implizite Aufrufe spezieller Methoden nur dann garantiert korrekt, wenn sie auf dem Typ eines Objekts definiert sind und nicht im Instanzwörterbuch des Objekts. Dieses Verhalten ist der Grund, warum 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 von speziellen Methoden wie __hash__() und __repr__(), die von allen Objekten, einschließlich Typobjekten, implementiert werden. Wenn die implizite Suche nach diesen Methoden den konventionellen Suchprozess verwenden würde, würden sie fehlschlagen, wenn sie auf dem Typobjekt selbst aufgerufen werden.

>>> 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 falsch versuchte Aufruf einer ungebundenen Methode einer Klasse auf diese Weise wird manchmal als „Metaklassenverwirrung“ bezeichnet und wird vermieden, indem die Instanz bei der Suche nach speziellen Methoden umgangen wird.

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

Zusätzlich zum Umgehen von Instanzattributen im Interesse der Korrektheit umgeht die implizite Suche nach speziellen Methoden im Allgemeinen auch die Methode __getattribute__(), selbst die des Metatyps des Objekts.

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

Das Umgehen der __getattribute__()-Mechanismen in dieser Weise bietet erhebliche Möglichkeiten für Geschwindigkeitsoptimierungen innerhalb des Interpreters, auf Kosten einiger Flexibilität bei der Handhabung spezieller Methoden (die spezielle Methode *muss* auf dem Klassenobjekt selbst gesetzt werden, um vom Interpreter konsistent aufgerufen zu werden).

3.4. Coroutinen

3.4.1. Awaitable Objects

Ein awaitable-Objekt implementiert im Allgemeinen eine __await__()-Methode. Coroutine-Objekte, die von async def-Funktionen zurückgegeben werden, sind awaitable.

Hinweis

Die Generator-Iterator-Objekte, die von Generatoren zurückgegeben werden, die mit types.coroutine() dekoriert sind, sind ebenfalls awaitable, aber sie implementieren keine __await__().

object.__await__(self)

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

Hinweis

Die Sprache legt keine Einschränkungen für den Typ oder den Wert der Objekte fest, die vom von __await__ zurückgegebenen Iterator erzeugt werden, da dies spezifisch für die Implementierung des asynchronen Ausführungs-Frameworks (z. B. asyncio) ist, das das awaitable-Objekt verwaltet.

Hinzugefügt in Version 3.5.

Siehe auch

PEP 492 für zusätzliche Informationen über awaitable-Objekte.

3.4.2. Coroutine Objects

Coroutine-Objekte sind awaitable-Objekte. Die Ausführung einer Coroutine kann gesteuert werden, indem __await__() aufgerufen und das Ergebnis iteriert wird. Wenn die Coroutine ihre Ausführung beendet und zurückkehrt, löst der Iterator StopIteration aus, und das Attribut value der Ausnahme enthält den Rückgabewert. Wenn die Coroutine eine Ausnahme auslöst, wird diese vom Iterator propagiert. Coroutinen sollten keine unbehandelten StopIteration-Ausnahmen direkt auslösen.

Coroutinen haben auch die unten aufgeführten Methoden, die analog zu denen von Generatoren sind (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, eine Coroutine mehr als einmal zu awaiten.

coroutine.send(value)

Startet oder setzt die Ausführung der Coroutine fort. Wenn value None ist, entspricht dies dem Vorschieben des von __await__() zurückgegebenen Iterators. Wenn value nicht None ist, delegiert diese Methode an die send()-Methode des Iterators, der die Coroutine zum Anhalten gebracht hat. Das Ergebnis (Rückgabewert, StopIteration oder eine andere Ausnahme) ist dasselbe wie beim Iterieren über den Rückgabewert von __await__(), wie oben beschrieben.

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

Löst die angegebene Ausnahme in der Coroutine aus. Diese Methode delegiert an die throw()-Methode des Iterators, der die Coroutine zum Anhalten gebracht hat, falls dieser eine solche Methode besitzt. Andernfalls wird die Ausnahme an der Anhaltestelle ausgelöst. Das Ergebnis (Rückgabewert, StopIteration oder eine andere Ausnahme) ist dasselbe wie beim Iterieren über den Rückgabewert von __await__(), wie oben beschrieben. Wenn die Ausnahme in der Coroutine nicht abgefangen wird, propagiert sie zurück zum Aufrufer.

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

coroutine.close()

Veranlasst die Coroutine, sich selbst aufzuräumen und zu beenden. Wenn die Coroutine angehalten ist, delegiert diese Methode zuerst an die close()-Methode des Iterators, der die Coroutine zum Anhalten gebracht hat, falls dieser eine solche Methode besitzt. Dann löst sie GeneratorExit an der Anhaltestelle aus, was dazu führt, dass sich die Coroutine sofort selbst aufräumt. Schließlich wird die Coroutine als beendet markiert, auch wenn sie nie gestartet wurde.

Coroutine-Objekte werden automatisch mit dem obigen Verfahren geschlossen, wenn sie zerstört werden.

3.4.3. Asynchronous Iterators

Ein asynchroner Iterator kann asynchronen Code in seiner __anext__-Methode aufrufen.

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

Die object-Klasse selbst stellt diese Methoden nicht bereit.

object.__aiter__(self)

Muss ein asynchrones Iterator-Objekt zurückgeben.

object.__anext__(self)

Muss ein awaitable zurückgeben, das zu einem nächsten Wert des Iterators aufgelöst wird. Sollte eine StopAsyncIteration-Ausnahme 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

Hinzugefügt 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. Die Rückgabe von etwas anderem führt zu einer TypeError-Ausnahme.

3.4.4. Asynchrone Kontextmanager

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

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

Die object-Klasse selbst stellt diese Methoden nicht bereit.

object.__aenter__(self)

Semantisch ähnlich zu __enter__(), der einzige Unterschied ist, dass es ein awaitable zurückgeben muss.

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

Semantisch ähnlich zu __exit__(), der einzige Unterschied ist, dass es ein awaitable zurückgeben muss.

Ein Beispiel für eine asynchrone Kontextmanagerklasse

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

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

Hinzugefügt in Version 3.5.

Fußnoten