Typobjektstrukturen¶
Vielleicht eine der wichtigsten Strukturen des Python-Objektsystems ist die Struktur, die einen neuen Typ definiert: die PyTypeObject-Struktur. Typobjekte können mit einer der PyObject_*- oder PyType_*-Funktionen behandelt werden, bieten aber für die meisten Python-Anwendungen nicht viel Interessantes. Diese Objekte sind grundlegend dafür, wie sich Objekte verhalten, und sind daher für den Interpreter selbst und für jedes Erweiterungsmodul, das neue Typen implementiert, sehr wichtig.
Typobjekte sind im Vergleich zu den meisten Standardtypen ziemlich groß. Der Grund für die Größe ist, dass jedes Typobjekt eine große Anzahl von Werten speichert, meist C-Funktionszeiger, von denen jeder einen kleinen Teil der Funktionalität des Typs implementiert. Die Felder des Typobjekts werden in diesem Abschnitt im Detail beschrieben. Die Felder werden in der Reihenfolge beschrieben, in der sie in der Struktur auftreten.
Zusätzlich zur folgenden Kurzübersicht bietet der Abschnitt Beispiele einen schnellen Einblick in die Bedeutung und Verwendung von PyTypeObject.
Kurzübersicht¶
„tp slots“¶
PyTypeObject Slot [1] |
spezielle Methoden/Attribute |
Info [2] |
||||
|---|---|---|---|---|---|---|
O |
T |
D |
I |
|||
<R> |
const char * |
__name__ |
X |
X |
||
X |
X |
X |
||||
X |
X |
|||||
X |
X |
X |
||||
X |
X |
|||||
__getattribute__, __getattr__ |
G |
|||||
__setattr__, __delattr__ |
G |
|||||
% |
||||||
__repr__ |
X |
X |
X |
|||
% |
||||||
% |
||||||
% |
||||||
__hash__ |
X |
G |
||||
__call__ |
X |
X |
||||
__str__ |
X |
X |
||||
__getattribute__, __getattr__ |
X |
X |
G |
|||
__setattr__, __delattr__ |
X |
X |
G |
|||
% |
||||||
unsigned long |
X |
X |
? |
|||
const char * |
__doc__ |
X |
X |
|||
X |
G |
|||||
X |
G |
|||||
__lt__, __le__, __eq__, __ne__, __gt__, __ge__ |
X |
G |
||||
X |
? |
|||||
__iter__ |
X |
|||||
__next__ |
X |
|||||
|
X |
X |
||||
|
X |
|||||
|
X |
X |
||||
__base__ |
X |
|||||
|
__dict__ |
? |
||||
__get__ |
X |
|||||
__set__, __delete__ |
X |
|||||
X |
? |
|||||
__init__ |
X |
X |
X |
|||
X |
? |
? |
||||
__new__ |
X |
X |
? |
? |
||
X |
X |
? |
? |
|||
X |
X |
|||||
< |
|
__bases__ |
~ |
|||
< |
|
__mro__ |
~ |
|||
[ |
|
|||||
void * |
__subclasses__ |
|||||
|
||||||
( |
||||||
unsigned int |
||||||
__del__ |
X |
|||||
unsigned char |
||||||
Unter-Slots¶
Slot |
spezielle Methoden |
|
|---|---|---|
__await__ |
||
__aiter__ |
||
__anext__ |
||
__add__ __radd__ |
||
__iadd__ |
||
__sub__ __rsub__ |
||
__isub__ |
||
__mul__ __rmul__ |
||
__imul__ |
||
__mod__ __rmod__ |
||
__imod__ |
||
__divmod__ __rdivmod__ |
||
__pow__ __rpow__ |
||
__ipow__ |
||
__neg__ |
||
__pos__ |
||
__abs__ |
||
__bool__ |
||
__invert__ |
||
__lshift__ __rlshift__ |
||
__ilshift__ |
||
__rshift__ __rrshift__ |
||
__irshift__ |
||
__and__ __rand__ |
||
__iand__ |
||
__xor__ __rxor__ |
||
__ixor__ |
||
__or__ __ror__ |
||
__ior__ |
||
__int__ |
||
void * |
||
__float__ |
||
__floordiv__ |
||
__ifloordiv__ |
||
__truediv__ |
||
__itruediv__ |
||
__index__ |
||
__matmul__ __rmatmul__ |
||
__imatmul__ |
||
__len__ |
||
__getitem__ |
||
__setitem__, __delitem__ |
||
__len__ |
||
__add__ |
||
__mul__ |
||
__getitem__ |
||
__setitem__ __delitem__ |
||
__contains__ |
||
__iadd__ |
||
__imul__ |
||
__buffer__ |
||
__release_buffer__ |
||
Slot-Typedefs¶
typedef |
Parameter-Typen |
Rückgabetyp |
|---|---|---|
|
||
|
void |
|
void * |
void |
|
int |
||
|
||
int |
||
|
|
|
PyObject *const char *
|
|
|
int |
||
|
||
int |
||
|
||
int |
||
|
Py_hash_t |
|
|
||
|
|
|
|
|
|
|
||
int |
||
void |
||
|
int |
|
PyObject * |
|
|
|
||
|
||
|
||
int |
||
int |
||
int |
Siehe Slot-Typedefs unten für weitere Details.
PyTypeObject-Definition¶
Die Strukturdefinition für PyTypeObject finden Sie in Include/cpython/object.h. Zur einfacheren Referenzierung wird hier die dort gefundene Definition wiederholt.
typedef struct _typeobject {
PyObject_VAR_HEAD
const char *tp_name; /* For printing, in format "<module>.<name>" */
Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
/* Methods to implement standard operations */
destructor tp_dealloc;
Py_ssize_t tp_vectorcall_offset;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
or tp_reserved (Python 3) */
reprfunc tp_repr;
/* Method suites for standard classes */
PyNumberMethods *tp_as_number;
PySequenceMethods *tp_as_sequence;
PyMappingMethods *tp_as_mapping;
/* More standard operations (here for binary compatibility) */
hashfunc tp_hash;
ternaryfunc tp_call;
reprfunc tp_str;
getattrofunc tp_getattro;
setattrofunc tp_setattro;
/* Functions to access object as input/output buffer */
PyBufferProcs *tp_as_buffer;
/* Flags to define presence of optional/expanded features */
unsigned long tp_flags;
const char *tp_doc; /* Documentation string */
/* Assigned meaning in release 2.0 */
/* call function for all accessible objects */
traverseproc tp_traverse;
/* delete references to contained objects */
inquiry tp_clear;
/* Assigned meaning in release 2.1 */
/* rich comparisons */
richcmpfunc tp_richcompare;
/* weak reference enabler */
Py_ssize_t tp_weaklistoffset;
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;
/* Attribute descriptor and subclassing stuff */
PyMethodDef *tp_methods;
PyMemberDef *tp_members;
PyGetSetDef *tp_getset;
// Strong reference on a heap type, borrowed reference on a static type
PyTypeObject *tp_base;
PyObject *tp_dict;
descrgetfunc tp_descr_get;
descrsetfunc tp_descr_set;
Py_ssize_t tp_dictoffset;
initproc tp_init;
allocfunc tp_alloc;
newfunc tp_new;
freefunc tp_free; /* Low-level free-memory routine */
inquiry tp_is_gc; /* For PyObject_IS_GC */
PyObject *tp_bases;
PyObject *tp_mro; /* method resolution order */
PyObject *tp_cache; /* no longer used */
void *tp_subclasses; /* for static builtin types this is an index */
PyObject *tp_weaklist; /* not used for static builtin types */
destructor tp_del;
/* Type attribute cache version tag. Added in version 2.6.
* If zero, the cache is invalid and must be initialized.
*/
unsigned int tp_version_tag;
destructor tp_finalize;
vectorcallfunc tp_vectorcall;
/* bitset of which type-watchers care about this type */
unsigned char tp_watched;
/* Number of tp_version_tag values used.
* Set to _Py_ATTR_CACHE_UNUSED if the attribute cache is
* disabled for this type (e.g. due to custom MRO entries).
* Otherwise, limited to MAX_VERSIONS_PER_CLASS (defined elsewhere).
*/
uint16_t tp_versions_used;
} PyTypeObject;
PyObject-Slots¶
Die Typobjektstruktur erweitert die PyVarObject-Struktur. Das Feld ob_size wird für dynamische Typen verwendet (erstellt durch type_new(), normalerweise aufgerufen von einer Klassendefinition). Beachten Sie, dass PyType_Type (der Metatyp) tp_itemsize initialisiert, was bedeutet, dass seine Instanzen (d. h. Typobjekte) das Feld ob_size *haben müssen*.
Die Referenzanzahl des Typobjekts wird durch das Makro
PyObject_HEAD_INITmit1initialisiert. Beachten Sie, dass bei statisch allozierten Typobjekten die Instanzen des Typs (Objekte, derenob_typeauf den Typ zurückverweist) *nicht* als Referenzen gezählt werden. Aber bei dynamisch allozierten Typobjekten zählen die Instanzen *als* Referenzen.Vererbung
Dieses Feld wird von Unterklassen nicht vererbt.
Dies ist der Typ des Typs, also sein Metatyp. Er wird durch das Argument für das Makro
PyObject_HEAD_INITinitialisiert und sein Wert sollte normalerweise&PyType_Typesein. Bei dynamisch ladbaren Erweiterungsmodulen, die (zumindest) unter Windows verwendbar sein müssen, beschwert sich der Compiler jedoch, dass dies keine gültige Initialisierung ist. Daher ist die Konvention,NULLan das MakroPyObject_HEAD_INITzu übergeben und dieses Feld explizit zu Beginn der Initialisierungsfunktion des Moduls zu initialisieren, bevor irgendetwas anderes getan wird. Dies geschieht typischerweise so:Foo_Type.ob_type = &PyType_Type;Dies sollte geschehen, bevor Instanzen des Typs erstellt werden.
PyType_Ready()prüft, obob_typeNULList und initialisiert es in diesem Fall mit dem Feldob_typeder Basisklasse.PyType_Ready()ändert dieses Feld nicht, wenn es ungleich null ist.Vererbung
Dieses Feld wird von Unterklassen vererbt.
PyVarObject-Slots¶
Für statisch alloziierte Typobjekte sollte dies auf null initialisiert werden. Für dynamisch allocierte Typobjekte hat dieses Feld eine spezielle interne Bedeutung.
Dieses Feld sollte über das Makro
Py_SIZE()zugegriffen werden.Vererbung
Dieses Feld wird von Unterklassen nicht vererbt.
PyTypeObject-Slots¶
Jeder Slot hat einen Abschnitt, der die Vererbung beschreibt. Wenn PyType_Ready() einen Wert setzen kann, wenn das Feld auf NULL gesetzt ist, gibt es auch einen Abschnitt „Standard“.
-
const char *PyTypeObject.tp_name¶
Zeiger auf eine NUL-terminierte Zeichenkette mit dem Namen des Typs. Für Typen, die als globale Variablen eines Moduls zugänglich sind, sollte die Zeichenkette der vollständige Modulname, gefolgt von einem Punkt, gefolgt vom Typnamen sein; für eingebaute Typen sollte es nur der Typname sein. Wenn das Modul ein Untermodul eines Pakets ist, ist der vollständige Paketname Teil des vollständigen Modulnamens. Zum Beispiel sollte ein Typ namens
T, der im ModulMim UnterpaketQim PaketPdefiniert ist, dentp_name-Initialisierer"P.Q.M.T"haben.Für dynamisch allocierte Typobjekte sollte dies nur der Typname sein, und der Modulname wird explizit im Typ-Dictionary unter dem Schlüssel
'__module__'gespeichert.Für statisch allocierte Typobjekte sollte das Feld tp_name einen Punkt enthalten. Alles vor dem letzten Punkt wird als Attribut
__module__zugänglich gemacht, und alles nach dem letzten Punkt wird als Attribut__name__zugänglich gemacht.Wenn kein Punkt vorhanden ist, wird das gesamte Feld
tp_nameals Attribut__name__zugänglich gemacht, und das Attribut__module__ist undefiniert (sofern es nicht explizit im Dictionary gesetzt wurde, wie oben erklärt). Das bedeutet, dass Ihr Typ nicht pickle-fähig ist. Außerdem wird er nicht in Modul-Dokumentationen aufgeführt, die mit pydoc erstellt wurden.Dieses Feld darf nicht
NULLsein. Es ist das einzige erforderliche Feld inPyTypeObject()(außer möglicherweisetp_itemsize).Vererbung
Dieses Feld wird von Unterklassen nicht vererbt.
-
Py_ssize_t PyTypeObject.tp_basicsize¶
-
Py_ssize_t PyTypeObject.tp_itemsize¶
Diese Felder ermöglichen die Berechnung der Größe von Instanzen des Typs in Bytes.
Es gibt zwei Arten von Typen: Typen mit festen Instanzlängen haben ein
tp_itemsize-Feld von Null, Typen mit variablen Instanzlängen haben eintp_itemsize-Feld ungleich Null. Für einen Typ mit festen Instanzlängen haben alle Instanzen die gleiche Größe, angegeben intp_basicsize. (Ausnahmen von dieser Regel können mitPyUnstable_Object_GC_NewWithExtraData()gemacht werden.)Für einen Typ mit variablen Instanzlängen müssen die Instanzen ein Feld
ob_sizehaben, und die Instanzgröße isttp_basicsizeplus N maltp_itemsize, wobei N die „Länge“ des Objekts ist.Funktionen wie
PyObject_NewVar()nehmen den Wert von N als Argument und speichern ihn im Feldob_sizeder Instanz. Beachten Sie, dass das Feldob_sizespäter für andere Zwecke verwendet werden kann. Zum Beispiel verwendenint-Instanzen die Bits vonob_sizeauf eine implementierungsdefinierte Weise; der zugrunde liegende Speicher und seine Größe sollten überPyLong_Export()abgerufen werden.Hinweis
Auf das Feld
ob_sizesollte über die MakrosPy_SIZE()undPy_SET_SIZE()zugegriffen werden.Auch die Anwesenheit eines Feldes
ob_sizeim Instanzlayout bedeutet nicht, dass die Instanzstruktur variable Länge hat. Zum Beispiel hat der Typlistfeste Instanzlängen, aber diese Instanzen haben ein Feldob_size. (Wie beiint, vermeiden Sie den direkten Zugriff aufob_sizevon Listen. Rufen Sie stattdessenPyList_Size()auf.)Die Größe
tp_basicsizebeinhaltet die für Daten destp_basedes Typs benötigte Größe, plus alle zusätzlichen Daten, die von jeder Instanz benötigt werden.Der richtige Weg,
tp_basicsizezu setzen, ist die Verwendung dessizeof-Operators auf der Struktur, die zur Deklaration des Instanzlayouts verwendet wird. Diese Struktur muss die Struktur enthalten, die zur Deklaration des Basistyps verwendet wird. Mit anderen Worten,tp_basicsizemuss größer oder gleich demtp_basicsizedes Basis-Typs sein.Da jeder Typ eine Unterklasse von
objectist, muss diese StrukturPyObjectoderPyVarObjectenthalten (abhängig davon, obob_sizeenthalten sein soll). Diese werden normalerweise durch das MakroPyObject_HEADoderPyObject_VAR_HEADdefiniert, entsprechend.Die Basisgröße beinhaltet nicht die Größe des GC-Headers, da dieser Header nicht Teil von
PyObject_HEADist.Für Fälle, in denen die zur Deklaration des Basistyps verwendete Struktur unbekannt ist, siehe
PyType_Spec.basicsizeundPyType_FromMetaclass().Hinweise zur Ausrichtung
tp_basicsizemuss ein Vielfaches von_Alignof(PyObject)sein. Wennsizeofauf einerstructverwendet wird, diePyObject_HEADenthält, wie empfohlen, stellt der Compiler dies sicher. Wenn keine Cstructverwendet wird oder wenn Compiler-Erweiterungen wie__attribute__((packed))verwendet werden, liegt dies in Ihrer Verantwortung.Wenn die variablen Elemente eine bestimmte Ausrichtung erfordern, müssen
tp_basicsizeundtp_itemsizejeweils ein Vielfaches dieser Ausrichtung sein. Wenn beispielsweise der variable Teil eines Typs einendoublespeichert, liegt es in Ihrer Verantwortung, dass beide Felder ein Vielfaches von_Alignof(double)sind.
Vererbung
Diese Felder werden separat von Unterklassen vererbt. (Das heißt, wenn das Feld auf Null gesetzt ist, kopiert
PyType_Ready()den Wert vom Basistyp, was darauf hinweist, dass die Instanzen keinen zusätzlichen Speicherplatz benötigen.)Wenn der Basistyp ein
tp_itemsizeungleich Null hat, ist es im Allgemeinen nicht sicher,tp_itemsizein einer Unterklasse auf einen anderen Wert ungleich Null zu setzen (obwohl dies von der Implementierung des Basistyps abhängt).
-
destructor PyTypeObject.tp_dealloc¶
Ein Zeiger auf die Instanzzerstörungsfunktion. Die Funktionssignatur lautet:
void tp_dealloc(PyObject *self);
Die Zerstörungsfunktion sollte alle Referenzen entfernen, die die Instanz besitzt (z. B.
Py_CLEAR()aufrufen), alle von der Instanz besessenen Speicherpuffer freigeben und die Funktiontp_freedes Typs aufrufen, um das Objekt selbst freizugeben.Wenn Sie Funktionen aufrufen können, die den Fehlerindikator setzen können, müssen Sie
PyErr_GetRaisedException()undPyErr_SetRaisedException()verwenden, um sicherzustellen, dass Sie einen bereits vorhandenen Fehlerindikator nicht überschreiben (die Deallokation könnte während der Verarbeitung eines anderen Fehlers aufgetreten sein).static void foo_dealloc(foo_object *self) { PyObject *et, *ev, *etb; PyObject *exc = PyErr_GetRaisedException(); ... PyErr_SetRaisedException(exc); }
Der Deallocator selbst darf keine Ausnahme auslösen; wenn er auf einen Fehlerfall stößt, sollte er
PyErr_FormatUnraisable()aufrufen, um eine nicht behebbare Ausnahme zu protokollieren (und zu löschen).Es werden keine Garantien dafür übernommen, wann ein Objekt zerstört wird, außer
Python wird ein Objekt sofort oder einige Zeit nach dem Löschen der letzten Referenz auf das Objekt zerstören, es sei denn, sein Finalizer (
tp_finalize) belebt das Objekt anschließend wieder.Ein Objekt wird nicht zerstört, während es automatisch finalisiert (
tp_finalize) oder automatisch gelöscht (tp_clear) wird.
CPython zerstört ein Objekt derzeit sofort mit
Py_DECREF(), wenn der neue Referenzzähler null ist, aber dies kann sich in einer zukünftigen Version ändern.Es wird empfohlen,
PyObject_CallFinalizerFromDealloc()am Anfang vontp_deallocaufzurufen, um sicherzustellen, dass das Objekt vor der Zerstörung immer finalisiert wird.Wenn der Typ Garbage Collection unterstützt (das Flag
Py_TPFLAGS_HAVE_GCgesetzt ist), sollte der DestruktorPyObject_GC_UnTrack()aufrufen, bevor er alle Mitgliedsfelder löscht.Es ist zulässig,
tp_clearvontp_deallocaus aufzurufen, um Code-Duplizierung zu reduzieren und sicherzustellen, dass das Objekt vor der Zerstörung immer gelöscht wird. Beachten Sie, dasstp_clearmöglicherweise bereits aufgerufen wurde.Wenn der Typ heap-allokiert ist (
Py_TPFLAGS_HEAPTYPE), sollte der Dealloziator die eigene Referenz auf sein Typobjekt (überPy_DECREF()) freigeben, nachdem der Typ-Dealloziator aufgerufen wurde. Siehe das folgende Beispiel.static void foo_dealloc(PyObject *op) { foo_object *self = (foo_object *) op; PyObject_GC_UnTrack(self); Py_CLEAR(self->ref); Py_TYPE(self)->tp_free(self); }
tp_deallocmuss den Ausnahmezustand unverändert lassen. Wenn er etwas aufrufen muss, das eine Ausnahme auslösen könnte, muss der Ausnahmezustand zuerst gesichert und später wiederhergestellt werden (nachdem Ausnahmen mitPyErr_WriteUnraisable()protokolliert wurden).Beispiel
static void foo_dealloc(PyObject *self) { PyObject *exc = PyErr_GetRaisedException(); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // self was resurrected. goto done; } PyTypeObject *tp = Py_TYPE(self); if (tp->tp_flags & Py_TPFLAGS_HAVE_GC) { PyObject_GC_UnTrack(self); } // Optional, but convenient to avoid code duplication. if (tp->tp_clear && tp->tp_clear(self) < 0) { PyErr_WriteUnraisable(self); } // Any additional destruction goes here. tp->tp_free(self); self = NULL; // In case PyErr_WriteUnraisable() is called below. if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE) { Py_CLEAR(tp); } done: // Optional, if something was called that might have raised an // exception. if (PyErr_Occurred()) { PyErr_WriteUnraisable(self); } PyErr_SetRaisedException(exc); }
tp_deallockann von jedem Python-Thread aufgerufen werden, nicht nur von dem Thread, der das Objekt erstellt hat (wenn das Objekt Teil eines Referenzzählungszyklus wird, kann dieser Zyklus von einer Garbage Collection auf jedem Thread gesammelt werden). Dies ist für Python-API-Aufrufe kein Problem, da der Thread, auf demtp_deallocmit einem angehängten Thread-Zustand aufgerufen wird. Wenn das zu zerstörende Objekt wiederum Objekte aus einer anderen C-Bibliothek zerstört, ist jedoch darauf zu achten, dass die Zerstörung dieser Objekte auf dem Thread, dertp_deallocaufgerufen hat, keine Annahmen der Bibliothek verletzt.Vererbung
Dieses Feld wird von Unterklassen vererbt.
Siehe auch
Objektlebenszyklus für Details, wie dieser Slot mit anderen Slots zusammenhängt.
-
Py_ssize_t PyTypeObject.tp_vectorcall_offset¶
Ein optionaler Offset zu einer pro-Instanz-Funktion, die den Aufruf des Objekts mit dem Vectorcall-Protokoll implementiert, einer effizienteren Alternative zu
tp_call.Dieses Feld wird nur verwendet, wenn das Flag
Py_TPFLAGS_HAVE_VECTORCALLgesetzt ist. In diesem Fall muss es eine positive Ganzzahl sein, die den Offset einervectorcallfunc-Zeigers in der Instanz enthält.Der vectorcallfunc-Zeiger kann
NULLsein. In diesem Fall verhält sich die Instanz so, als wärePy_TPFLAGS_HAVE_VECTORCALLnicht gesetzt: Der Aufruf der Instanz fällt auftp_callzurück.Jede Klasse, die
Py_TPFLAGS_HAVE_VECTORCALLsetzt, muss auchtp_callsetzen und sicherstellen, dass dessen Verhalten mit der vectorcallfunc-Funktion konsistent ist. Dies kann durch Setzen von tp_call aufPyVectorcall_Call()erfolgen.Geändert in Version 3.8: Vor Version 3.8 hieß dieses Feld
tp_print. In Python 2.x wurde es zum Drucken auf eine Datei verwendet. In Python 3.0 bis 3.7 war es ungenutzt.Geändert in Version 3.12: Vor Version 3.12 wurde es für veränderliche Heap-Typen nicht empfohlen, das Vectorcall-Protokoll zu implementieren. Wenn ein Benutzer
__call__in Python-Code setzt, wird nur tp_call aktualisiert, was wahrscheinlich zu Inkonsistenzen mit der Vectorcall-Funktion führt. Seit 3.12 deaktiviert das Setzen von__call__die Vectorcall-Optimierung, indem das FlagPy_TPFLAGS_HAVE_VECTORCALLgelöscht wird.Vererbung
Dieses Feld wird immer vererbt. Das Flag
Py_TPFLAGS_HAVE_VECTORCALLwird jedoch nicht immer vererbt. Wenn es nicht gesetzt ist, verwendet die Unterklasse kein Vectorcall, es sei denn,PyVectorcall_Call()wird explizit aufgerufen.
-
getattrfunc PyTypeObject.tp_getattr¶
Ein optionaler Zeiger auf die Funktion zum Abrufen von Attributen als Zeichenkette.
Dieses Feld ist veraltet. Wenn es definiert ist, sollte es auf eine Funktion zeigen, die sich wie die Funktion
tp_getattroverhält, aber einen C-String anstelle eines Python-String-Objekts als Attributnamen nimmt.Vererbung
Gruppe:
tp_getattr,tp_getattroDieses Feld wird zusammen mit
tp_getattrovon Unterklassen geerbt: Eine Unterklasse erbt sowohltp_getattrals auchtp_getattrovon ihrer Basisklasse, wenn dietp_getattrundtp_getattroder Unterklasse beideNULLsind.
-
setattrfunc PyTypeObject.tp_setattr¶
Ein optionaler Zeiger auf die Funktion zum Setzen und Löschen von Attributen.
Dieses Feld ist veraltet. Wenn es definiert ist, sollte es auf eine Funktion zeigen, die sich wie die Funktion
tp_setattroverhält, aber einen C-String anstelle eines Python-String-Objekts als Attributnamen nimmt.Vererbung
Gruppe:
tp_setattr,tp_setattroDieses Feld wird zusammen mit
tp_setattrovon Unterklassen geerbt: Eine Unterklasse erbt sowohltp_setattrals auchtp_setattrovon ihrer Basisklasse, wenn dietp_setattrundtp_setattroder Unterklasse beideNULLsind.
-
PyAsyncMethods *PyTypeObject.tp_as_async¶
Zeiger auf eine zusätzliche Struktur, die Felder enthält, die nur für Objekte relevant sind, die awaitable und asynchrone Iteratorprotokolle auf C-Ebene implementieren. Siehe Asynchrone Objektstrukturen für Details.
Hinzugefügt in Version 3.5: Früher bekannt als
tp_compareundtp_reserved.Vererbung
Das Feld
tp_as_asyncwird nicht vererbt, aber die enthaltenen Felder werden einzeln vererbt.
-
reprfunc PyTypeObject.tp_repr¶
Ein optionaler Zeiger auf eine Funktion, die die eingebaute Funktion
repr()implementiert.Die Signatur ist dieselbe wie für
PyObject_Repr()PyObject *tp_repr(PyObject *self);
Die Funktion muss eine Zeichenkette oder ein Unicode-Objekt zurückgeben. Idealerweise sollte diese Funktion eine Zeichenkette zurückgeben, die, wenn sie in
eval()übergeben wird, mit einer geeigneten Umgebung ein Objekt mit demselben Wert zurückgibt. Wenn dies nicht machbar ist, sollte sie eine Zeichenkette zurückgeben, die mit'<'beginnt und mit'>'endet, aus der sowohl der Typ als auch der Wert des Objekts abgeleitet werden können.Vererbung
Dieses Feld wird von Unterklassen vererbt.
Standard
Wenn dieses Feld nicht gesetzt ist, wird eine Zeichenkette der Form
<%s object at %p>zurückgegeben, wobei%sdurch den Typnamen und%pdurch die Speicheradresse des Objekts ersetzt wird.
-
PyNumberMethods *PyTypeObject.tp_as_number¶
Zeiger auf eine zusätzliche Struktur, die Felder enthält, die nur für Objekte relevant sind, die das Zahlenprotokoll implementieren. Diese Felder sind in Zahlenobjektstrukturen dokumentiert.
Vererbung
Das Feld
tp_as_numberwird nicht vererbt, aber die enthaltenen Felder werden einzeln vererbt.
-
PySequenceMethods *PyTypeObject.tp_as_sequence¶
Zeiger auf eine zusätzliche Struktur, die Felder enthält, die nur für Objekte relevant sind, die das Sequenzprotokoll implementieren. Diese Felder sind in Sequenzobjektstrukturen dokumentiert.
Vererbung
Das Feld
tp_as_sequencewird nicht vererbt, aber die enthaltenen Felder werden einzeln vererbt.
-
PyMappingMethods *PyTypeObject.tp_as_mapping¶
Zeiger auf eine zusätzliche Struktur, die Felder enthält, die nur für Objekte relevant sind, die das Mapping-Protokoll implementieren. Diese Felder sind in Mapping-Objektstrukturen dokumentiert.
Vererbung
Das Feld
tp_as_mappingwird nicht vererbt, aber die enthaltenen Felder werden einzeln vererbt.
-
hashfunc PyTypeObject.tp_hash¶
Ein optionaler Zeiger auf eine Funktion, die die eingebaute Funktion
hash()implementiert.Die Signatur ist dieselbe wie für
PyObject_Hash()Py_hash_t tp_hash(PyObject *);
Der Wert
-1sollte nicht als normaler Rückgabewert zurückgegeben werden; wenn bei der Berechnung des Hash-Werts ein Fehler auftritt, sollte die Funktion eine Ausnahme setzen und-1zurückgeben.Wenn dieses Feld nicht gesetzt ist (und
tp_richcomparenicht gesetzt ist), löst ein Versuch, das Objekt zu hashen,TypeErroraus. Dies ist dasselbe, als würde es aufPyObject_HashNotImplemented()gesetzt.Dieses Feld kann explizit auf
PyObject_HashNotImplemented()gesetzt werden, um die Vererbung der Hash-Methode von einem übergeordneten Typ zu blockieren. Dies wird als Äquivalent zu__hash__ = Noneauf Python-Ebene interpretiert, wodurchisinstance(o, collections.Hashable)korrektFalsezurückgibt. Beachten Sie, dass das Gegenteil auch gilt: das Setzen von__hash__ = Nonefür eine Klasse auf Python-Ebene führt dazu, dass dertp_hash-Slot aufPyObject_HashNotImplemented()gesetzt wird.Vererbung
Gruppe:
tp_hash,tp_richcompareDieses Feld wird zusammen mit
tp_richcomparevon Unterklassen geerbt: Eine Unterklasse erbt sowohltp_richcompareals auchtp_hash, wenn dietp_richcompareundtp_hashder Unterklasse beideNULLsind.Standard
PyBaseObject_TypeverwendetPyObject_GenericHash().
-
ternaryfunc PyTypeObject.tp_call¶
Ein optionaler Zeiger auf eine Funktion, die den Aufruf des Objekts implementiert. Dieser sollte
NULLsein, wenn das Objekt nicht aufrufbar ist. Die Signatur ist dieselbe wie fürPyObject_Call()PyObject *tp_call(PyObject *self, PyObject *args, PyObject *kwargs);
Vererbung
Dieses Feld wird von Unterklassen vererbt.
-
reprfunc PyTypeObject.tp_str¶
Ein optionaler Zeiger auf eine Funktion, die die eingebaute Operation
str()implementiert. (Beachten Sie, dassstrjetzt ein Typ ist undstr()den Konstruktor für diesen Typ aufruft. Dieser Konstruktor ruftPyObject_Str()auf, um die eigentliche Arbeit zu erledigen, undPyObject_Str()ruft diesen Handler auf.)Die Signatur ist dieselbe wie für
PyObject_Str()PyObject *tp_str(PyObject *self);
Die Funktion muss eine Zeichenkette oder ein Unicode-Objekt zurückgeben. Sie sollte eine „freundliche“ Zeichenkettedarstellung des Objekts sein, da dies die Darstellung ist, die unter anderem von der Funktion
print()verwendet wird.Vererbung
Dieses Feld wird von Unterklassen vererbt.
Standard
Wenn dieses Feld nicht gesetzt ist, wird
PyObject_Repr()aufgerufen, um eine Zeichenkettedarstellung zurückzugeben.
-
getattrofunc PyTypeObject.tp_getattro¶
Ein optionaler Zeiger auf die Funktion zum Abrufen von Attributen.
Die Signatur ist dieselbe wie für
PyObject_GetAttr()PyObject *tp_getattro(PyObject *self, PyObject *attr);
Es ist normalerweise praktisch, dieses Feld auf
PyObject_GenericGetAttr()zu setzen, das die normale Methode zum Suchen von Objektattributen implementiert.Vererbung
Gruppe:
tp_getattr,tp_getattroDieses Feld wird zusammen mit
tp_getattrvon Unterklassen geerbt: Eine Unterklasse erbt sowohltp_getattrals auchtp_getattrovon ihrer Basisklasse, wenn dietp_getattrundtp_getattroder Unterklasse beideNULLsind.Standard
PyBaseObject_TypeverwendetPyObject_GenericGetAttr().
-
setattrofunc PyTypeObject.tp_setattro¶
Ein optionaler Zeiger auf die Funktion zum Setzen und Löschen von Attributen.
Die Signatur ist dieselbe wie für
PyObject_SetAttr()int tp_setattro(PyObject *self, PyObject *attr, PyObject *value);
Zusätzlich muss das Setzen von value auf
NULLzum Löschen eines Attributs unterstützt werden. Es ist normalerweise praktisch, dieses Feld aufPyObject_GenericSetAttr()zu setzen, das die normale Methode zum Setzen von Objektattributen implementiert.Vererbung
Gruppe:
tp_setattr,tp_setattroDieses Feld wird zusammen mit
tp_setattrvon Unterklassen geerbt: Eine Unterklasse erbt sowohltp_setattrals auchtp_setattrovon ihrer Basisklasse, wenn dietp_setattrundtp_setattroder Unterklasse beideNULLsind.Standard
PyBaseObject_TypeverwendetPyObject_GenericSetAttr().
-
PyBufferProcs *PyTypeObject.tp_as_buffer¶
Zeiger auf eine zusätzliche Struktur, die Felder enthält, die nur für Objekte relevant sind, die die Puffer-Schnittstelle implementieren. Diese Felder sind in Pufferobjektstrukturen dokumentiert.
Vererbung
Das Feld
tp_as_bufferwird nicht vererbt, aber die enthaltenen Felder werden einzeln vererbt.
-
unsigned long PyTypeObject.tp_flags¶
Dieses Feld ist eine Bitmaske verschiedener Flags. Einige Flags geben unterschiedliche Semantiken für bestimmte Situationen an; andere werden verwendet, um anzuzeigen, dass bestimmte Felder im Typobjekt (oder in den Erweiterungsstrukturen, auf die über
tp_as_number,tp_as_sequence,tp_as_mappingundtp_as_bufferverwiesen wird) gültig sind, die historisch nicht immer vorhanden waren. Wenn ein solches Flag-Bit gelöscht ist, dürfen die von ihm geschützten Typfelder nicht zugegriffen werden und müssen stattdessen als Null oderNULLbehandelt werden.Vererbung
Die Vererbung dieses Feldes ist kompliziert. Die meisten Flag-Bits werden individuell vererbt, d.h. wenn der Basistyp ein Flag-Bit gesetzt hat, erbt der Subtyp dieses Flag-Bit. Die Flag-Bits, die sich auf Erweiterungsstrukturen beziehen, werden streng vererbt, wenn die Erweiterungsstruktur vererbt wird, d.h. der Wert des Flag-Bits des Basistyps wird zusammen mit einem Zeiger auf die Erweiterungsstruktur in den Subtyp kopiert. Das Flag-Bit
Py_TPFLAGS_HAVE_GCwird zusammen mit den Felderntp_traverseundtp_clearvererbt, d.h. wenn das Flag-BitPy_TPFLAGS_HAVE_GCim Subtyp nicht gesetzt ist und die Feldertp_traverseundtp_clearim Subtyp existieren und den WertNULLhaben.Standard
PyBaseObject_TypeverwendetPy_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE.Bitmasken
Die folgenden Bitmasken sind derzeit definiert; sie können mit dem Operator
|zu einem Wert für das Feldtp_flagskombiniert werden. Das MakroPyType_HasFeature()nimmt einen Typ und einen Flags-Wert, tp und f, und prüft, obtp->tp_flags & fungleich Null ist.-
Py_TPFLAGS_HEAPTYPE¶
Dieses Bit ist gesetzt, wenn das Typobjekt selbst auf dem Heap allokiert wird, z.B. Typen, die dynamisch mit
PyType_FromSpec()erstellt werden. In diesem Fall wird das Feldob_typeseiner Instanzen als Verweis auf den Typ betrachtet, und das Typobjekt wird bei der Erstellung einer neuen Instanz mit INCREF und bei der Zerstörung einer Instanz mit DECREF inkrementiert (dies gilt nicht für Instanzen von Subtypen; nur der vom ob_type der Instanz referenzierte Typ wird inkrementiert oder dekrementiert). Heap-Typen müssen auch die Garbage Collection unterstützen, da sie mit ihrem eigenen Modulobjekt Zyklusreferenzen bilden können.Vererbung
???
-
Py_TPFLAGS_BASETYPE¶
Dieses Bit ist gesetzt, wenn der Typ als Basistyp für einen anderen Typ verwendet werden kann. Wenn dieses Bit nicht gesetzt ist, kann der Typ nicht als Subtyp verwendet werden (ähnlich einer "finalen" Klasse in Java).
Vererbung
???
-
Py_TPFLAGS_READY¶
Dieses Bit ist gesetzt, wenn das Typobjekt durch
PyType_Ready()vollständig initialisiert wurde.Vererbung
???
-
Py_TPFLAGS_READYING¶
Dieses Bit ist gesetzt, während
PyType_Ready()mit der Initialisierung des Typobjekts beschäftigt ist.Vererbung
???
-
Py_TPFLAGS_HAVE_GC¶
Dieses Bit ist gesetzt, wenn das Objekt die Garbage Collection unterstützt. Wenn dieses Bit gesetzt ist, muss der Speicher für neue Instanzen (siehe
tp_alloc) mitPyObject_GC_NewoderPyType_GenericAlloc()allokiert und (siehetp_free) mitPyObject_GC_Del()freigegeben werden. Weitere Informationen finden Sie in Abschnitt Unterstützung der zyklischen Garbage Collection.Vererbung
Gruppe:
Py_TPFLAGS_HAVE_GC,tp_traverse,tp_clearDas Flag-Bit
Py_TPFLAGS_HAVE_GCwird zusammen mit den Felderntp_traverseundtp_clearvererbt, d.h. wenn das Flag-BitPy_TPFLAGS_HAVE_GCim Subtyp nicht gesetzt ist und die Feldertp_traverseundtp_clearim Subtyp existieren und den WertNULLhaben.
-
Py_TPFLAGS_DEFAULT¶
Dies ist eine Bitmaske aller Bits, die für die Existenz bestimmter Felder im Typobjekt und seinen Erweiterungsstrukturen relevant sind. Derzeit sind folgende Bits enthalten:
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION.Vererbung
???
-
Py_TPFLAGS_METHOD_DESCRIPTOR¶
Dieses Bit zeigt an, dass Objekte sich wie ungebundene Methoden verhalten.
Wenn dieses Flag für
type(meth)gesetzt ist, dannmeth.__get__(obj, cls)(*args, **kwds)(wobeiobjnicht None ist) muss äquivalent zumeth(obj, *args, **kwds)sein.meth.__get__(None, cls)(*args, **kwds)muss äquivalent zumeth(*args, **kwds)sein.
Dieses Flag ermöglicht eine Optimierung für typische Methodenaufrufe wie
obj.meth(): es vermeidet die Erstellung eines temporären "gebundenen Methoden"-Objekts fürobj.meth.Hinzugefügt in Version 3.8.
Vererbung
Dieses Flag wird niemals von Typen vererbt, bei denen das Flag
Py_TPFLAGS_IMMUTABLETYPEnicht gesetzt ist. Für Erweiterungstypen wird es immer vererbt, wenntp_descr_getvererbt wird.
-
Py_TPFLAGS_MANAGED_DICT¶
Dieses Bit zeigt an, dass Instanzen der Klasse ein Attribut
__dict__haben und dass der Platz für das Dictionary vom VM verwaltet wird.Wenn dieses Flag gesetzt ist, sollte auch
Py_TPFLAGS_HAVE_GCgesetzt sein.Die Typ-Traversierungsfunktion muss
PyObject_VisitManagedDict()aufrufen und ihre Clear-Funktion mussPyObject_ClearManagedDict()aufrufen.Hinzugefügt in Version 3.12.
Vererbung
Dieses Flag wird vererbt, es sei denn, das Feld
tp_dictoffsetist in einer Oberklasse gesetzt.
-
Py_TPFLAGS_MANAGED_WEAKREF¶
Dieses Bit zeigt an, dass Instanzen der Klasse schwach referenzierbar sein sollten.
Hinzugefügt in Version 3.12.
Vererbung
Dieses Flag wird vererbt, es sei denn, das Feld
tp_weaklistoffsetist in einer Oberklasse gesetzt.
-
Py_TPFLAGS_ITEMS_AT_END¶
Nur verwendbar mit Typen variabler Größe, d.h. mit einem von Null verschiedenen
tp_itemsize.Zeigt an, dass der variable Teil einer Instanz dieses Typs am Ende des Speicherbereichs der Instanz liegt, in einem Offset von
Py_TYPE(obj)->tp_basicsize(der sich in jeder Unterklasse unterscheiden kann).Beim Setzen dieses Flags stellen Sie sicher, dass alle Oberklassen dieses Speicherlayout verwenden oder keine variable Größe haben. Python prüft dies nicht.
Hinzugefügt in Version 3.12.
Vererbung
Dieses Flag wird vererbt.
-
Py_TPFLAGS_LONG_SUBCLASS¶
-
Py_TPFLAGS_LIST_SUBCLASS¶
-
Py_TPFLAGS_TUPLE_SUBCLASS¶
-
Py_TPFLAGS_BYTES_SUBCLASS¶
-
Py_TPFLAGS_UNICODE_SUBCLASS¶
-
Py_TPFLAGS_DICT_SUBCLASS¶
-
Py_TPFLAGS_BASE_EXC_SUBCLASS¶
-
Py_TPFLAGS_TYPE_SUBCLASS¶
Diese Flags werden von Funktionen wie
PyLong_Check()verwendet, um schnell zu prüfen, ob ein Typ eine Unterklasse eines integrierten Typs ist; solche spezifischen Prüfungen sind schneller als eine allgemeine Prüfung wiePyObject_IsInstance(). Benutzerdefinierte Typen, die von integrierten Typen erben, sollten ihretp_flagsentsprechend setzen, andernfalls verhält sich der Code, der mit solchen Typen interagiert, unterschiedlich, je nachdem, welche Art von Prüfung verwendet wird.
-
Py_TPFLAGS_HAVE_FINALIZE¶
Dieses Bit ist gesetzt, wenn der Slot
tp_finalizein der Typstruktur vorhanden ist.Hinzugefügt in Version 3.4.
Veraltet seit Version 3.8: Dieses Flag ist nicht mehr notwendig, da der Interpreter davon ausgeht, dass der Slot
tp_finalizeimmer in der Typstruktur vorhanden ist.
-
Py_TPFLAGS_HAVE_VECTORCALL¶
Dieses Bit ist gesetzt, wenn die Klasse das Vektoraufrufprotokoll implementiert. Details finden Sie unter
tp_vectorcall_offset.Vererbung
Dieses Bit wird vererbt, wenn auch
tp_callvererbt wird.Hinzugefügt in Version 3.9.
Geändert in Version 3.12: Dieses Flag wird nun aus einer Klasse entfernt, wenn die Methode
__call__()der Klasse neu zugewiesen wird.Dieses Flag kann nun von veränderlichen Klassen vererbt werden.
-
Py_TPFLAGS_IMMUTABLETYPE¶
Dieses Bit ist für Typobjekte gesetzt, die unveränderlich sind: Typattribute können weder gesetzt noch gelöscht werden.
PyType_Ready()wendet dieses Flag automatisch auf statische Typen an.Vererbung
Dieses Flag wird nicht vererbt.
Hinzugefügt in Version 3.10.
-
Py_TPFLAGS_DISALLOW_INSTANTIATION¶
Verhindert die Erstellung von Instanzen des Typs: setzen Sie
tp_newauf NULL und erstellen Sie nicht den Schlüssel__new__im Typ-Dictionary.Das Flag muss vor der Erstellung des Typs gesetzt werden, nicht danach. Zum Beispiel muss es gesetzt werden, bevor
PyType_Ready()für den Typ aufgerufen wird.Das Flag wird automatisch auf statische Typen gesetzt, wenn
tp_baseNULL oder&PyBaseObject_Typeist undtp_newNULL ist.Vererbung
Dieses Flag wird nicht vererbt. Allerdings werden Unterklassen nicht instanziierbar sein, es sei denn, sie stellen ein Nicht-NULL-
tp_newbereit (was nur über die C-API möglich ist).Hinweis
Um die direkte Instanziierung einer Klasse zu verhindern, aber die Instanziierung ihrer Unterklassen zu ermöglichen (z.B. für eine abstrakte Basisklasse), verwenden Sie dieses Flag nicht. Machen Sie stattdessen
tp_newnur für Unterklassen erfolgreich.Hinzugefügt in Version 3.10.
-
Py_TPFLAGS_MAPPING¶
Dieses Bit zeigt an, dass Instanzen der Klasse Mapping-Muster übereinstimmen können, wenn sie als Subjekt eines
match-Blocks verwendet werden. Es wird automatisch gesetzt, wenncollections.abc.Mappingregistriert oder als Unterklasse verwendet wird, und zurückgesetzt, wenncollections.abc.Sequenceregistriert wird.Hinweis
Py_TPFLAGS_MAPPINGundPy_TPFLAGS_SEQUENCEsind gegenseitig ausschließend; es ist ein Fehler, beide Flags gleichzeitig zu aktivieren.Vererbung
Dieses Flag wird von Typen vererbt, die
Py_TPFLAGS_SEQUENCEnicht bereits gesetzt haben.Siehe auch
PEP 634 – Strukturelle Mustererkennung: Spezifikation
Hinzugefügt in Version 3.10.
-
Py_TPFLAGS_SEQUENCE¶
Dieses Bit zeigt an, dass Instanzen der Klasse Sequenzmuster übereinstimmen können, wenn sie als Subjekt eines
match-Blocks verwendet werden. Es wird automatisch gesetzt, wenncollections.abc.Sequenceregistriert oder als Unterklasse verwendet wird, und zurückgesetzt, wenncollections.abc.Mappingregistriert wird.Hinweis
Py_TPFLAGS_MAPPINGundPy_TPFLAGS_SEQUENCEsind gegenseitig ausschließend; es ist ein Fehler, beide Flags gleichzeitig zu aktivieren.Vererbung
Dieses Flag wird von Typen vererbt, die
Py_TPFLAGS_MAPPINGnicht bereits gesetzt haben.Siehe auch
PEP 634 – Strukturelle Mustererkennung: Spezifikation
Hinzugefügt in Version 3.10.
-
Py_TPFLAGS_VALID_VERSION_TAG¶
Intern. Dieses Flag darf nicht gesetzt oder gelöscht werden. Um anzuzeigen, dass eine Klasse geändert wurde, rufen Sie
PyType_Modified()auf.Warnung
Dieses Flag ist in Header-Dateien vorhanden, wird aber nicht verwendet. Es wird in einer zukünftigen Version von CPython entfernt.
-
Py_TPFLAGS_HEAPTYPE¶
-
const char *PyTypeObject.tp_doc¶
Ein optionaler Zeiger auf eine NUL-terminierte C-Zeichenkette, die den Docstring für dieses Typobjekt enthält. Dies wird als Attribut
__doc__für den Typ und seine Instanzen bereitgestellt.Vererbung
Dieses Feld wird von Subtypen *nicht* vererbt.
-
traverseproc PyTypeObject.tp_traverse¶
Ein optionaler Zeiger auf eine Traversierungsfunktion für den Garbage Collector. Dies wird nur verwendet, wenn das Flag-Bit
Py_TPFLAGS_HAVE_GCgesetzt ist. Die Signatur lautetint tp_traverse(PyObject *self, visitproc visit, void *arg);
Weitere Informationen zu Pythons Garbage Collection finden Sie in Abschnitt Unterstützung der zyklischen Garbage Collection.
Der Zeiger
tp_traversewird vom Garbage Collector verwendet, um Referenzzyklen zu erkennen. Eine typische Implementierung einertp_traverse-Funktion ruft einfachPy_VISIT()für jedes Mitglied der Instanz auf, das ein Python-Objekt ist und das die Instanz besitzt. Zum Beispiel ist dies die Funktionlocal_traverse()aus dem_thread-Erweiterungsmodul.static int local_traverse(PyObject *op, visitproc visit, void *arg) { localobject *self = (localobject *) op; Py_VISIT(self->args); Py_VISIT(self->kw); Py_VISIT(self->dict); return 0; }
Beachten Sie, dass
Py_VISIT()nur für diejenigen Mitglieder aufgerufen wird, die an Referenzzyklen teilnehmen können. Obwohl es auch einself->key-Mitglied gibt, kann dies nurNULLoder ein Python-String sein und daher nicht Teil eines Referenzzyklus sein.Auf der anderen Seite, selbst wenn Sie wissen, dass ein Mitglied niemals Teil eines Zyklus sein kann, können Sie es als Debugging-Hilfe trotzdem besuchen, damit die Funktion
gc.get_referents()des Modulsgces einschließt.Heap-Typen (
Py_TPFLAGS_HEAPTYPE) müssen ihren Typ mitPy_VISIT(Py_TYPE(self));
Dies ist nur seit Python 3.9 erforderlich. Um Python 3.8 und älter zu unterstützen, muss diese Zeile bedingt sein.
#if PY_VERSION_HEX >= 0x03090000 Py_VISIT(Py_TYPE(self)); #endif
Wenn das Bit
Py_TPFLAGS_MANAGED_DICTim Feldtp_flagsgesetzt ist, muss die TraversierungsfunktionPyObject_VisitManagedDict()wie folgt aufrufen:PyObject_VisitManagedDict((PyObject*)self, visit, arg);
Warnung
Bei der Implementierung von
tp_traversemüssen nur die Mitglieder besucht werden, die die Instanz *besitzt* (indem sie starke Referenzen auf sie hat). Wenn ein Objekt beispielsweise schwache Referenzen über den Slottp_weaklistunterstützt, darf der Zeiger, der die verkettete Liste unterstützt (worauf *tp_weaklist* zeigt), *nicht* besucht werden, da die Instanz keine direkten starken Referenzen auf die Elemente darin hält (da sie entfernt werden dürfen, auch wenn die Instanz noch lebt).Beachten Sie, dass
Py_VISIT()die Parameter visit und arg vonlocal_traverse()mit diesen spezifischen Namen benötigt; benennen Sie sie nicht beliebig.Instanzen von heap-allokierten Typen halten eine Referenz auf ihren Typ. Ihre Traversierungsfunktion muss daher entweder
Py_TYPE(self)besuchen oder diese Verantwortung durch Aufruf vontp_traverseeines anderen heap-allokierten Typs (z.B. einer heap-allokierten Oberklasse) delegieren. Wenn sie dies nicht tun, wird der Typobjekt möglicherweise nicht vom Garbage Collector gesammelt.Hinweis
Die Funktion
tp_traversekann von jedem Thread aufgerufen werden.Geändert in Version 3.9: Heap-allokierte Typen müssen
Py_TYPE(self)intp_traversebesuchen. In früheren Python-Versionen konnte dies aufgrund von Bug 40217 zu Abstürzen in Unterklassen führen.Vererbung
Gruppe:
Py_TPFLAGS_HAVE_GC,tp_traverse,tp_clearDieses Feld wird von Subtypen zusammen mit
tp_clearund dem Flag-BitPy_TPFLAGS_HAVE_GCvererbt: das Flag-Bit,tp_traverseundtp_clearwerden alle vom Basistyp geerbt, wenn sie im Subtyp alle Null sind.
-
inquiry PyTypeObject.tp_clear¶
Ein optionaler Zeiger auf eine Clear-Funktion. Die Signatur lautet
int tp_clear(PyObject *);
Der Zweck dieser Funktion ist es, Referenzzyklen zu brechen, die eine zyklische Isolierung verursachen, damit die Objekte sicher zerstört werden können. Ein geleertes Objekt ist ein teilweise zerstörtes Objekt; das Objekt ist nicht verpflichtet, Design-Invarianten zu erfüllen, die während der normalen Nutzung gelten.
tp_clearmuss keine Referenzen auf Objekte löschen, die nicht an Referenzzyklen teilnehmen können, wie z.B. Python-Strings oder Python-Integers. Es kann jedoch praktisch sein, alle Referenzen zu löschen und dietp_dealloc-Funktion des Typs so zu schreiben, dass sietp_clearaufruft, um Code-Duplizierung zu vermeiden. (Vorsicht:tp_clearwurde möglicherweise bereits aufgerufen. Bevorzugen Sie den Aufruf von idempotenten Funktionen wiePy_CLEAR().)Jegliche nicht-triviale Bereinigung sollte in
tp_finalizeanstelle vontp_clearerfolgen.Hinweis
Wenn
tp_cleareinen Referenzzyklus nicht brechen kann, können die Objekte in der zyklischen Isolierung ungesammelt bleiben ("lecken"). Siehegc.garbage.Hinweis
Referenzen (direkt und indirekt) könnten bereits geleert worden sein; sie sind nicht garantiert in einem konsistenten Zustand.
Hinweis
Die Funktion
tp_clearkann von jedem Thread aufgerufen werden.Hinweis
Es ist nicht garantiert, dass ein Objekt automatisch geleert wird, bevor sein Destruktor (
tp_dealloc) aufgerufen wird.Diese Funktion unterscheidet sich vom Destruktor (
tp_dealloc) in folgenden PunktenDer Zweck des Leerns eines Objekts ist es, Referenzen auf andere Objekte zu entfernen, die an einem Referenzzyklus beteiligt sein könnten. Der Zweck des Destruktors hingegen ist eine Obermenge: er muss *alle* von ihm besessenen Ressourcen freigeben, einschließlich Referenzen auf Objekte, die nicht an einem Referenzzyklus teilnehmen können (z.B. Ganzzahlen) sowie den eigenen Speicher des Objekts (durch Aufruf von
tp_free).Wenn
tp_clearaufgerufen wird, können andere Objekte immer noch Referenzen auf das zu leerende Objekt halten. Aus diesem Grund darftp_clearden eigenen Speicher des Objekts nicht freigeben (tp_free). Der Destruktor hingegen wird nur aufgerufen, wenn keine (starken) Referenzen existieren, und muss daher das Objekt selbst sicher zerstören, indem er es freigibt.tp_clearwird möglicherweise niemals automatisch aufgerufen. Der Destruktor eines Objekts wird hingegen einige Zeit nachdem das Objekt nicht mehr erreichbar ist (d.h. es gibt keine Referenzen mehr auf das Objekt oder das Objekt ist Mitglied eines zyklischen Isolats), automatisch aufgerufen.
Es werden keine Garantien dafür übernommen, wann, ob oder wie oft Python ein Objekt automatisch bereinigt, außer
Python wird ein Objekt nicht automatisch bereinigen, wenn es erreichbar ist, d.h. wenn es eine Referenz darauf gibt und es kein Mitglied eines zyklischen Isolats ist.
Python wird ein Objekt nicht automatisch bereinigen, wenn es noch nicht automatisch finalisiert wurde (siehe
tp_finalize). (Wenn der Finalizer das Objekt wiederbelebt hat, kann das Objekt vor der Bereinigung möglicherweise wieder automatisch finalisiert werden oder auch nicht.)Wenn ein Objekt Mitglied eines zyklischen Isolats ist, wird Python es nicht automatisch bereinigen, wenn irgendein Mitglied des zyklischen Isolats noch nicht automatisch finalisiert wurde (
tp_finalize).Python wird ein Objekt erst zerstören, nachdem alle automatischen Aufrufe seiner
tp_clear-Funktion zurückgekehrt sind. Dies stellt sicher, dass der Vorgang des Aufbrechens eines Referenzzyklus denself-Zeiger nicht ungültig macht, währendtp_clearnoch ausgeführt wird.Python wird die Funktion
tp_clearnicht mehrmals gleichzeitig aufrufen.
CPython bereinigt Objekte derzeit nur automatisch, wenn dies zur Unterbrechung von Referenzzyklen in einem zyklischen Isolat erforderlich ist, aber zukünftige Versionen könnten Objekte regelmäßig vor ihrer Zerstörung bereinigen.
Zusammengenommen müssen alle
tp_clear-Funktionen im System alle Referenzzyklen aufbrechen. Dies ist subtil, und im Zweifelsfall sollte einetp_clear-Funktion bereitgestellt werden. Zum Beispiel implementiert der Tupel-Typ keinetp_clear-Funktion, da nachweisbar ist, dass kein Referenzzyklus ausschließlich aus Tupeln bestehen kann. Daher sind dietp_clear-Funktionen anderer Typen dafür verantwortlich, jeden Zyklus aufzubrechen, der ein Tupel enthält. Dies ist nicht sofort ersichtlich und es gibt selten einen guten Grund, die Implementierung vontp_clearzu vermeiden.Implementierungen von
tp_clearsollten die Referenzen der Instanz auf ihre Mitglieder, die Python-Objekte sein können, aufheben und ihre Zeiger auf diese Mitglieder aufNULLsetzen, wie im folgenden Beispielstatic int local_clear(PyObject *op) { localobject *self = (localobject *) op; Py_CLEAR(self->key); Py_CLEAR(self->args); Py_CLEAR(self->kw); Py_CLEAR(self->dict); return 0; }
Das Makro
Py_CLEAR()sollte verwendet werden, da das Löschen von Referenzen heikel ist: Die Referenz auf das enthaltene Objekt darf nicht freigegeben werden (mittelsPy_DECREF()), bevor der Zeiger auf das enthaltene Objekt aufNULLgesetzt ist. Dies liegt daran, dass die Freigabe der Referenz dazu führen kann, dass das enthaltene Objekt zur Bereinigung markiert wird, was eine Kette von Bereinigungsaktivitäten auslösen kann, die die Ausführung von beliebigem Python-Code beinhalten kann (aufgrund von Finalizern oder Weakref-Callbacks, die mit dem enthaltenen Objekt verbunden sind). Wenn es möglich ist, dass solcher Code wieder *self* referenziert, ist es wichtig, dass der Zeiger auf das enthaltene Objekt zu diesem ZeitpunktNULList, damit *self* weiß, dass das enthaltene Objekt nicht mehr verwendet werden kann. Das MakroPy_CLEAR()führt die Operationen in einer sicheren Reihenfolge aus.Wenn das Bit
Py_TPFLAGS_MANAGED_DICTim Feldtp_flagsgesetzt ist, muss die Clear-FunktionPyObject_ClearManagedDict()wie folgt aufrufenPyObject_ClearManagedDict((PyObject*)self);
Weitere Informationen zu Pythons Garbage Collection finden Sie in Abschnitt Unterstützung der zyklischen Garbage Collection.
Vererbung
Gruppe:
Py_TPFLAGS_HAVE_GC,tp_traverse,tp_clearDieses Feld wird von Untertypen geerbt, zusammen mit
tp_traverseund dem Flag-BitPy_TPFLAGS_HAVE_GC: Das Flag-Bit,tp_traverseundtp_clearwerden alle vom Basistyp geerbt, wenn sie im Untertyp alle Null sind.Siehe auch
Objektlebenszyklus für Details, wie dieser Slot mit anderen Slots zusammenhängt.
-
richcmpfunc PyTypeObject.tp_richcompare¶
Ein optionaler Zeiger auf die Rich-Comparison-Funktion, deren Signatur lautet
PyObject *tp_richcompare(PyObject *self, PyObject *other, int op);
Der erste Parameter ist garantiert eine Instanz des Typs, der von
PyTypeObjectdefiniert wird.Die Funktion sollte das Ergebnis des Vergleichs zurückgeben (normalerweise
Py_TrueoderPy_False). Wenn der Vergleich undefiniert ist, muss siePy_NotImplementedzurückgeben; wenn ein anderer Fehler aufgetreten ist, muss sieNULLzurückgeben und eine Ausnahmesituation setzen.Die folgenden Konstanten sind definiert, um als dritter Argument für
tp_richcompareund fürPyObject_RichCompare()verwendet zu werdenKonstante
Vergleich
-
Py_LT¶
<-
Py_LE¶
<=-
Py_EQ¶
==-
Py_NE¶
!=-
Py_GT¶
>-
Py_GE¶
>=Das folgende Makro ist definiert, um das Schreiben von Rich-Comparison-Funktionen zu erleichtern
-
Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, op)¶
Gibt
Py_TrueoderPy_Falseaus der Funktion zurück, abhängig vom Ergebnis eines Vergleichs. VAL_A und VAL_B müssen durch C-Vergleichsoperatoren ordnungsfähig sein (z.B. können sie C-Integers oder -Floats sein). Das dritte Argument gibt die angeforderte Operation an, wie fürPyObject_RichCompare().Der zurückgegebene Wert ist eine neue starke Referenz.
Bei Fehlern wird eine Ausnahme gesetzt und die Funktion gibt
NULLzurück.Hinzugefügt in Version 3.7.
Vererbung
Gruppe:
tp_hash,tp_richcompareDieses Feld wird von Untertypen geerbt, zusammen mit
tp_hash: Ein Untertyp erbttp_richcompareundtp_hash, wenntp_richcompareundtp_hashdes Untertyps beideNULLsind.Standard
PyBaseObject_Typestellt einetp_richcompare-Implementierung bereit, die geerbt werden kann. Wenn jedoch nurtp_hashdefiniert ist, wird nicht einmal die geerbte Funktion verwendet und Instanzen des Typs können an keinen Vergleichen teilnehmen.-
Py_LT¶
-
Py_ssize_t PyTypeObject.tp_weaklistoffset¶
Während dieses Feld noch unterstützt wird, sollte
Py_TPFLAGS_MANAGED_WEAKREFstattdessen verwendet werden, wenn möglich.Wenn die Instanzen dieses Typs schwach referenzierbar sind, ist dieses Feld größer als Null und enthält den Offset in der Instanzstruktur des Schwachreferenzlistenkopfs (GC-Header, falls vorhanden, wird ignoriert); dieser Offset wird von
PyObject_ClearWeakRefs()und denPyWeakref_*-Funktionen verwendet. Die Instanzstruktur muss ein Feld vom Typ PyObject* enthalten, das mitNULLinitialisiert wird.Verwechseln Sie dieses Feld nicht mit
tp_weaklist; das ist der Listen-Kopf für schwache Referenzen auf das Typobjekt selbst.Es ist ein Fehler, sowohl das Bit
Py_TPFLAGS_MANAGED_WEAKREFals auchtp_weaklistoffsetzu setzen.Vererbung
Dieses Feld wird von Untertypen geerbt, siehe jedoch die unten aufgeführten Regeln. Ein Untertyp kann diesen Offset überschreiben; dies bedeutet, dass der Untertyp einen anderen Schwachreferenzlisten-Kopf als der Basistyp verwendet. Da der Listen-Kopf immer über
tp_weaklistoffsetgefunden wird, sollte dies kein Problem darstellen.Standard
Wenn das Bit
Py_TPFLAGS_MANAGED_WEAKREFim Feldtp_flagsgesetzt ist, wirdtp_weaklistoffsetauf einen negativen Wert gesetzt, um anzuzeigen, dass die Verwendung dieses Feldes unsicher ist.
-
getiterfunc PyTypeObject.tp_iter¶
Ein optionaler Zeiger auf eine Funktion, die einen Iterator für das Objekt zurückgibt. Seine Anwesenheit signalisiert normalerweise, dass die Instanzen dieses Typs iterierbar sind (obwohl Sequenzen ohne diese Funktion iterierbar sein können).
Diese Funktion hat die gleiche Signatur wie
PyObject_GetIter()PyObject *tp_iter(PyObject *self);
Vererbung
Dieses Feld wird von Unterklassen vererbt.
-
iternextfunc PyTypeObject.tp_iternext¶
Ein optionaler Zeiger auf eine Funktion, die das nächste Element in einem Iterator zurückgibt. Die Signatur lautet
PyObject *tp_iternext(PyObject *self);
Wenn der Iterator erschöpft ist, muss er
NULLzurückgeben; eineStopIteration-Ausnahme kann gesetzt sein oder auch nicht. Wenn ein anderer Fehler auftritt, muss er ebenfallsNULLzurückgeben. Seine Anwesenheit signalisiert, dass die Instanzen dieses Typs Iteratoren sind.Iterator-Typen sollten auch die Funktion
tp_iterdefinieren, und diese Funktion sollte die Iterator-Instanz selbst zurückgeben (nicht eine neue Iterator-Instanz).Diese Funktion hat die gleiche Signatur wie
PyIter_Next().Vererbung
Dieses Feld wird von Unterklassen vererbt.
-
struct PyMethodDef *PyTypeObject.tp_methods¶
Ein optionaler Zeiger auf ein statisches, mit
NULLabgeschlossenes Array vonPyMethodDef-Strukturen, die reguläre Methoden dieses Typs deklarieren.Für jeden Eintrag im Array wird ein Eintrag im Wörterbuch des Typs (siehe
tp_dictunten) erstellt, der einen Methodendeskriptor enthält.Vererbung
Dieses Feld wird von Untertypen nicht geerbt (Methoden werden über einen anderen Mechanismus geerbt).
-
struct PyMemberDef *PyTypeObject.tp_members¶
Ein optionaler Zeiger auf ein statisches, mit
NULLabgeschlossenes Array vonPyMemberDef-Strukturen, die reguläre Datenmember (Felder oder Slots) von Instanzen dieses Typs deklarieren.Für jeden Eintrag im Array wird ein Eintrag im Wörterbuch des Typs (siehe
tp_dictunten) erstellt, der einen Member-Deskriptor enthält.Vererbung
Dieses Feld wird von Untertypen nicht geerbt (Member werden über einen anderen Mechanismus geerbt).
-
struct PyGetSetDef *PyTypeObject.tp_getset¶
Ein optionaler Zeiger auf ein statisches, mit
NULLabgeschlossenes Array vonPyGetSetDef-Strukturen, die berechnete Attribute von Instanzen dieses Typs deklarieren.Für jeden Eintrag im Array wird ein Eintrag im Wörterbuch des Typs (siehe
tp_dictunten) erstellt, der einen Getset-Deskriptor enthält.Vererbung
Dieses Feld wird von Untertypen nicht geerbt (berechnete Attribute werden über einen anderen Mechanismus geerbt).
-
PyTypeObject *PyTypeObject.tp_base¶
Ein optionaler Zeiger auf einen Basistyp, von dem Typ-Eigenschaften geerbt werden. Auf dieser Ebene wird nur Einfachvererbung unterstützt; Mehrfachvererbung erfordert das dynamische Erstellen eines Typobjekts durch Aufruf der Metaklasse.
Hinweis
Die Initialisierung von Slots unterliegt den Regeln der Initialisierung von Globals. C99 verlangt, dass die Initialisierer "Adresskonstanten" sind. Funktionsdeskriptoren wie
PyType_GenericNew(), mit impliziter Umwandlung in einen Zeiger, sind gültige C99-Adresskonstanten.Der unäre '&'-Operator, angewendet auf eine nicht-statische Variable wie
PyBaseObject_Type, muss jedoch keine Adresskonstante ergeben. Compiler können dies unterstützen (gcc tut dies), MSVC nicht. Beide Compiler sind in diesem speziellen Verhalten streng standardkonform.Folglich sollte
tp_basein der Init-Funktion des Erweiterungsmoduls gesetzt werden.Vererbung
Dieses Feld wird von Untertypen nicht geerbt (offensichtlich).
Standard
Dieses Feld hat den Standardwert
&PyBaseObject_Type(was für Python-Programmierer als Typobjectbekannt ist).
-
PyObject *PyTypeObject.tp_dict¶
Das Wörterbuch des Typs wird hier von
PyType_Ready()gespeichert.Dieses Feld sollte normalerweise vor dem Aufruf von PyType_Ready auf
NULLinitialisiert werden; es kann auch mit einem Wörterbuch initialisiert werden, das anfängliche Attribute für den Typ enthält. NachdemPyType_Ready()den Typ initialisiert hat, können zusätzliche Attribute für den Typ zu diesem Wörterbuch hinzugefügt werden, sofern sie nicht überladenen Operationen entsprechen (wie__add__()). Sobald die Initialisierung für den Typ abgeschlossen ist, sollte dieses Feld als schreibgeschützt behandelt werden.Einige Typen speichern ihr Wörterbuch möglicherweise nicht in diesem Slot. Verwenden Sie
PyType_GetDict(), um das Wörterbuch für einen beliebigen Typ abzurufen.Geändert in Version 3.12: Interne Details: Für statische eingebaute Typen ist dies immer
NULL. Stattdessen wird das Wörterbuch für solche Typen aufPyInterpreterStategespeichert. Verwenden SiePyType_GetDict(), um das Wörterbuch für einen beliebigen Typ abzurufen.Vererbung
Dieses Feld wird von Untertypen nicht geerbt (obwohl die hier definierten Attribute über einen anderen Mechanismus geerbt werden).
Standard
Wenn dieses Feld
NULList, weistPyType_Ready()ihm ein neues Wörterbuch zu.Warnung
Es ist nicht sicher,
PyDict_SetItem()auftp_dictanzuwenden oder es anderweitig mit der C-API für Wörterbücher zu ändern.
-
descrgetfunc PyTypeObject.tp_descr_get¶
Ein optionaler Zeiger auf eine "Deskriptor-Get"-Funktion.
Die Funktion Signatur lautet
PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);
Vererbung
Dieses Feld wird von Unterklassen vererbt.
-
descrsetfunc PyTypeObject.tp_descr_set¶
Ein optionaler Zeiger auf eine Funktion zum Setzen und Löschen eines Deskriptorwerts.
Die Funktion Signatur lautet
int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);
Das *value*-Argument wird auf
NULLgesetzt, um den Wert zu löschen.Vererbung
Dieses Feld wird von Unterklassen vererbt.
-
Py_ssize_t PyTypeObject.tp_dictoffset¶
Während dieses Feld noch unterstützt wird, sollte
Py_TPFLAGS_MANAGED_DICTstattdessen verwendet werden, wenn möglich.Wenn die Instanzen dieses Typs ein Wörterbuch mit Instanzvariablen haben, ist dieses Feld ungleich Null und enthält den Offset in den Instanzen des Typs des Instanzvariablen-Wörterbuchs; dieser Offset wird von
PyObject_GenericGetAttr()verwendet.Verwechseln Sie dieses Feld nicht mit
tp_dict; das ist das Wörterbuch für Attribute des Typobjekts selbst.Der Wert gibt den Offset des Wörterbuchs vom Anfang der Instanzstruktur an.
tp_dictoffsetsollte als schreibgeschützt betrachtet werden. Um den Zeiger auf das Wörterbuch zu erhalten, rufen SiePyObject_GenericGetDict()auf. Das Aufrufen vonPyObject_GenericGetDict()kann die Zuweisung von Speicher für das Wörterbuch erfordern, daher kann es effizienter sein,PyObject_GetAttr()aufzurufen, wenn auf ein Attribut des Objekts zugegriffen wird.Es ist ein Fehler, sowohl das Bit
Py_TPFLAGS_MANAGED_DICTals auchtp_dictoffsetzu setzen.Vererbung
Dieses Feld wird von Untertypen geerbt. Ein Untertyp sollte diesen Offset nicht überschreiben; dies könnte unsicher sein, wenn C-Code versucht, auf das Dictionary am vorherigen Offset zuzugreifen. Um die Vererbung ordnungsgemäß zu unterstützen, verwenden Sie
Py_TPFLAGS_MANAGED_DICT.Standard
Dieser Slot hat keinen Standardwert. Für statische Typen wird, wenn das Feld
NULList, kein__dict__für Instanzen erstellt.Wenn das
Py_TPFLAGS_MANAGED_DICTBit im Feldtp_flagsgesetzt ist, wirdtp_dictoffsetauf-1gesetzt, um anzuzeigen, dass die Verwendung dieses Feldes unsicher ist.
-
initproc PyTypeObject.tp_init¶
Ein optionaler Zeiger auf eine Instanzinitialisierungsfunktion.
Diese Funktion entspricht der Methode
__init__()von Klassen. Wie bei__init__()ist es möglich, eine Instanz zu erstellen, ohne__init__()aufzurufen, und es ist möglich, eine Instanz neu zu initialisieren, indem ihre__init__()Methode erneut aufgerufen wird.Die Funktion Signatur lautet
int tp_init(PyObject *self, PyObject *args, PyObject *kwds);
Das Argument `self` ist die zu initialisierende Instanz; die Argumente `args` und `kwds` repräsentieren Positions- und Schlüsselwortargumente des Aufrufs von
__init__().Die Funktion
tp_init, falls nichtNULL, wird aufgerufen, wenn eine Instanz normalerweise durch Aufrufen ihres Typs erstellt wird, nachdem die Funktiontp_newdes Typs eine Instanz des Typs zurückgegeben hat. Wenn die Funktiontp_neweine Instanz eines anderen Typs zurückgibt, der kein Untertyp des ursprünglichen Typs ist, wird keine Funktiontp_initaufgerufen; wenntp_neweine Instanz eines Untertyps des ursprünglichen Typs zurückgibt, wird die Funktiontp_initdes Untertyps aufgerufen.Gibt bei Erfolg
0zurück, bei einem Fehler-1und setzt eine Ausnahme.Vererbung
Dieses Feld wird von Unterklassen vererbt.
Standard
Für statische Typen hat dieses Feld keinen Standardwert.
-
allocfunc PyTypeObject.tp_alloc¶
Ein optionaler Zeiger auf eine Instanzzuweisungsfunktion.
Die Funktion Signatur lautet
PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems);
Vererbung
Statische Untertypen erben diesen Slot, der
PyType_GenericAlloc()ist, wenn er vonobjectgeerbt wird.Heap-Untertypen erben diesen Slot nicht.
Standard
Für Heap-Untertypen ist dieses Feld immer auf
PyType_GenericAlloc()gesetzt.Für statische Untertypen wird dieser Slot geerbt (siehe oben).
-
newfunc PyTypeObject.tp_new¶
Ein optionaler Zeiger auf eine Instanzerstellungsfunktion.
Die Funktion Signatur lautet
PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds);
Das Argument `subtype` ist der Typ des zu erstellenden Objekts; die Argumente `args` und `kwds` repräsentieren Positions- und Schlüsselwortargumente des Aufrufs des Typs. Beachten Sie, dass `subtype` nicht mit dem Typ übereinstimmen muss, dessen Funktion
tp_newaufgerufen wird; es kann ein Untertyp dieses Typs sein (aber kein unrelateder Typ).Die Funktion
tp_newsolltesubtype->tp_alloc(subtype, nitems)aufrufen, um Speicher für das Objekt zuzuweisen, und dann nur so viel weitere Initialisierung vornehmen, wie absolut notwendig ist. Initialisierung, die sicher ignoriert oder wiederholt werden kann, sollte in den Handlertp_initverschoben werden. Eine gute Faustregel ist, dass für unveränderliche Typen die gesamte Initialisierung intp_newerfolgen sollte, während für veränderliche Typen der Großteil der Initialisierung auftp_initverschoben werden sollte.Setzen Sie das Flag
Py_TPFLAGS_DISALLOW_INSTANTIATION, um die Erstellung von Instanzen des Typs in Python zu verhindern.Vererbung
Dieses Feld wird von Untertypen geerbt, mit der Ausnahme, dass es nicht von statischen Typen geerbt wird, deren
tp_baseNULLoder&PyBaseObject_Typeist.Standard
Für statische Typen hat dieses Feld keinen Standardwert. Das bedeutet, wenn der Slot als
NULLdefiniert ist, kann der Typ nicht aufgerufen werden, um neue Instanzen zu erstellen; wahrscheinlich gibt es eine andere Möglichkeit, Instanzen zu erstellen, wie z. B. eine Factory-Funktion.
-
freefunc PyTypeObject.tp_free¶
Ein optionaler Zeiger auf eine Instanzdeallokierungsfunktion. Ihre Signatur ist
void tp_free(void *self);
Diese Funktion muss den von
tp_alloczugewiesenen Speicher freigeben.Vererbung
Statische Untertypen erben diesen Slot, der
PyObject_Free()ist, wenn er vonobjectgeerbt wird. Ausnahme: Wenn der Typ Garbage Collection unterstützt (d. h. das FlagPy_TPFLAGS_HAVE_GCim Feldtp_flagsgesetzt ist) und erPyObject_Free()erben würde, wird dieser Slot nicht geerbt, sondern standardmäßig aufPyObject_GC_Del()gesetzt.Heap-Untertypen erben diesen Slot nicht.
Standard
Für Heap-Untertypen ist dieser Slot standardmäßig ein Deallokator, der zu
PyType_GenericAlloc()und dem Wert des FlagsPy_TPFLAGS_HAVE_GCpasst.Für statische Untertypen wird dieser Slot geerbt (siehe oben).
-
inquiry PyTypeObject.tp_is_gc¶
Ein optionaler Zeiger auf eine Funktion, die vom Garbage Collector aufgerufen wird.
Der Garbage Collector muss wissen, ob ein bestimmtes Objekt sammelbar ist oder nicht. Normalerweise reicht es aus, das Feld
tp_flagsdes Typs des Objekts zu betrachten und das Bit des FlagsPy_TPFLAGS_HAVE_GCzu prüfen. Einige Typen haben jedoch eine Mischung aus statisch und dynamisch zugewiesenen Instanzen, und die statisch zugewiesenen Instanzen sind nicht sammelbar. Solche Typen sollten diese Funktion definieren; sie sollte1für eine sammelbare Instanz und0für eine nicht sammelbare Instanz zurückgeben. Die Signatur istint tp_is_gc(PyObject *self);
(Das einzige Beispiel hierfür sind Typen selbst. Der Metatyp,
PyType_Type, definiert diese Funktion, um zwischen statisch und dynamisch zugewiesenen Typen zu unterscheiden.)Vererbung
Dieses Feld wird von Unterklassen vererbt.
Standard
Dieser Slot hat keinen Standardwert. Wenn dieses Feld
NULList, wirdPy_TPFLAGS_HAVE_GCals funktionales Äquivalent verwendet.
-
PyObject *PyTypeObject.tp_bases¶
Tupel der Basistypen.
Dieses Feld sollte auf
NULLgesetzt und als schreibgeschützt behandelt werden. Python füllt es aus, wenn der Typinitialisiertwird.Für dynamisch erstellte Klassen kann der Slot
Py_tp_basesanstelle des Arguments `bases` vonPyType_FromSpecWithBases()verwendet werden. Die Argumentform wird bevorzugt.Warnung
Mehrfachvererbung funktioniert für statisch definierte Typen nicht gut. Wenn Sie
tp_basesauf ein Tupel setzen, wird Python keinen Fehler auslösen, aber einige Slots werden nur vom ersten Basis-Typ geerbt.Vererbung
Dieses Feld wird nicht geerbt.
-
PyObject *PyTypeObject.tp_mro¶
Tupel, das die erweiterte Menge der Basistypen enthält, beginnend mit dem Typ selbst und endend mit
object, in der Method Resolution Order.Dieses Feld sollte auf
NULLgesetzt und als schreibgeschützt behandelt werden. Python füllt es aus, wenn der Typinitialisiertwird.Vererbung
Dieses Feld wird nicht geerbt; es wird neu von
PyType_Ready()berechnet.
-
PyObject *PyTypeObject.tp_cache¶
Unbenutzt. Nur für interne Verwendung.
Vererbung
Dieses Feld wird nicht geerbt.
-
void *PyTypeObject.tp_subclasses¶
Eine Sammlung von Unterklassen. Nur für interne Verwendung. Kann ein ungültiger Zeiger sein.
Um eine Liste von Unterklassen zu erhalten, rufen Sie die Python-Methode
__subclasses__()auf.Geändert in Version 3.12: Für einige Typen enthält dieses Feld kein gültiges PyObject*. Der Typ wurde in void* geändert, um dies anzuzeigen.
Vererbung
Dieses Feld wird nicht geerbt.
-
PyObject *PyTypeObject.tp_weaklist¶
Kopf der Liste von Weak References, für Weak References auf dieses Typobjekt. Nicht geerbt. Nur für interne Verwendung.
Geändert in Version 3.12: Interna-Details: Für die statischen eingebauten Typen ist dies immer
NULL, auch wenn Weak References hinzugefügt werden. Stattdessen werden die Weak References für jeden aufPyInterpreterStategespeichert. Verwenden Sie die öffentliche C-API oder das interne Makro_PyObject_GET_WEAKREFS_LISTPTR(), um den Unterschied zu vermeiden.Vererbung
Dieses Feld wird nicht geerbt.
-
destructor PyTypeObject.tp_del¶
Dieses Feld ist veraltet. Verwenden Sie stattdessen
tp_finalize.
-
unsigned int PyTypeObject.tp_version_tag¶
Wird zur Indizierung des Methodencaches verwendet. Nur für interne Verwendung.
Vererbung
Dieses Feld wird nicht geerbt.
-
destructor PyTypeObject.tp_finalize¶
Ein optionaler Zeiger auf eine Instanzfinalisierungsfunktion. Dies ist die C-Implementierung der speziellen Methode
__del__(). Ihre Signatur istvoid tp_finalize(PyObject *self);
Der Hauptzweck der Finalisierung ist die Durchführung von nicht-trivialen Bereinigungsarbeiten, die vor der Zerstörung des Objekts durchgeführt werden müssen, während das Objekt und alle anderen Objekte, auf die es direkt oder indirekt verweist, sich noch in einem konsistenten Zustand befinden. Der Finalizer darf beliebigen Python-Code ausführen.
Bevor Python ein Objekt automatisch finalisiert, könnten einige der direkten oder indirekten Referenten des Objekts selbst automatisch finalisiert worden sein. Keiner der Referenten wurde jedoch automatisch gelöscht (siehe
tp_clear).Andere nicht-finalisierte Objekte könnten immer noch ein finalisiertes Objekt verwenden, daher muss der Finalizer das Objekt in einem sinnvollen Zustand hinterlassen (z. B. sind die Invarianten noch erfüllt).
Hinweis
Nachdem Python ein Objekt automatisch finalisiert hat, kann Python beginnen, das Objekt und seine Referenten automatisch zu löschen (siehe
tp_clear) (direkt und indirekt). Gelöschte Objekte befinden sich nicht zwangsläufig in einem konsistenten Zustand; ein finalisiertes Objekt muss gelöschte Referenten tolerieren können.Hinweis
Es gibt keine Garantie, dass ein Objekt automatisch finalisiert wird, bevor sein Destruktor (
tp_dealloc) aufgerufen wird. Es wird empfohlen,PyObject_CallFinalizerFromDealloc()am Anfang vontp_deallocaufzurufen, um sicherzustellen, dass das Objekt vor der Zerstörung immer finalisiert wird.Hinweis
Die Funktion
tp_finalizekann von jedem Thread aus aufgerufen werden, obwohl der GIL gehalten wird.Hinweis
Die Funktion
tp_finalizekann während des Herunterfahrens aufgerufen werden, nachdem einige globale Variablen gelöscht wurden. Siehe die Dokumentation der Methode__del__()für Details.Wenn Python ein Objekt finalisiert, verhält es sich wie der folgende Algorithmus:
Python kann das Objekt als *finalisiert* markieren. Derzeit markiert Python immer Objekte, deren Typ Garbage Collection unterstützt (d. h. das Flag
Py_TPFLAGS_HAVE_GCist im Feldtp_flagsgesetzt) und markiert niemals andere Arten von Objekten; dies könnte sich in einer zukünftigen Version ändern.Wenn das Objekt nicht als *finalisiert* markiert ist und seine Finalisierungsfunktion
tp_finalizenichtNULList, wird die Finalisierungsfunktion aufgerufen.Wenn die Finalisierungsfunktion aufgerufen wurde und die Finalisierung das Objekt erreichbar gemacht hat (d. h. es gibt eine Referenz auf das Objekt und es ist kein Mitglied eines zyklischen Isolats), dann hat die Finalisierung das Objekt *wiederbelebt*. Es ist nicht spezifiziert, ob die Finalisierung das Objekt auch durch Hinzufügen einer neuen Referenz wiederbeleben kann, die das Objekt nicht erreichbar macht, d. h. das Objekt ist (immer noch) ein Mitglied eines zyklischen Isolats.
Wenn die Finalisierung das Objekt wiederbelebt hat, wird die ausstehende Zerstörung des Objekts abgebrochen und die Markierung *finalisiert* des Objekts kann, falls vorhanden, entfernt werden. Derzeit entfernt Python niemals die Markierung *finalisiert*; dies könnte sich in einer zukünftigen Version ändern.
Unter *automatischer Finalisierung* versteht man jede Finalisierung, die von Python durchgeführt wird, außer über Aufrufe von
PyObject_CallFinalizer()oderPyObject_CallFinalizerFromDealloc(). Es werden keine Garantien gegeben, wann, ob oder wie oft ein Objekt automatisch finalisiert wird, außerPython wird ein Objekt nicht automatisch finalisieren, wenn es erreichbar ist, d. h. es gibt eine Referenz darauf und es ist kein Mitglied eines zyklischen Isolats.
Python wird ein Objekt nicht automatisch finalisieren, wenn die Finalisierung das Objekt nicht als *finalisiert* markieren würde. Derzeit gilt dies für Objekte, deren Typ keine Garbage Collection unterstützt, d. h. das Flag
Py_TPFLAGS_HAVE_GCist nicht gesetzt. Solche Objekte können immer noch manuell finalisiert werden, indemPyObject_CallFinalizer()oderPyObject_CallFinalizerFromDealloc()aufgerufen wird.Python wird keine zwei Mitglieder eines zyklischen Isolats gleichzeitig automatisch finalisieren.
Python wird ein Objekt nicht automatisch finalisieren, nachdem es das Objekt automatisch gelöscht hat (siehe
tp_clear).Wenn ein Objekt Mitglied eines zyklischen Isolats ist, wird Python es nicht automatisch finalisieren, nachdem es ein anderes Mitglied automatisch gelöscht hat (siehe
tp_clear).Python wird alle Mitglieder eines zyklischen Isolats automatisch finalisieren, bevor es eines davon automatisch löscht (siehe
tp_clear).Wenn Python ein Objekt automatisch löschen wird (siehe
tp_clear), wird es das Objekt zuerst automatisch finalisieren.
Python finalisiert derzeit nur Objekte, die Mitglieder eines zyklischen Isolats sind, aber zukünftige Versionen könnten Objekte regelmäßig vor ihrer Zerstörung finalisieren.
Um ein Objekt manuell zu finalisieren, rufen Sie diese Funktion nicht direkt auf; rufen Sie stattdessen
PyObject_CallFinalizer()oderPyObject_CallFinalizerFromDealloc()auf.tp_finalizesollte den aktuellen Ausnahmezustand unverändert lassen. Die empfohlene Methode, einen nicht trivialen Finalizer zu schreiben, besteht darin, die Ausnahme am Anfang zu sichern, indemPyErr_GetRaisedException()aufgerufen wird, und die Ausnahme am Ende wiederherzustellen, indemPyErr_SetRaisedException()aufgerufen wird. Wenn während der Ausführung des Finalizers eine Ausnahme auftritt, sollte diese mitPyErr_WriteUnraisable()oderPyErr_FormatUnraisable()protokolliert und gelöscht werden. Zum Beispielstatic void foo_finalize(PyObject *self) { // Save the current exception, if any. PyObject *exc = PyErr_GetRaisedException(); // ... if (do_something_that_might_raise() != success_indicator) { PyErr_WriteUnraisable(self); goto done; } done: // Restore the saved exception. This silently discards any exception // raised above, so be sure to call PyErr_WriteUnraisable first if // necessary. PyErr_SetRaisedException(exc); }
Vererbung
Dieses Feld wird von Unterklassen vererbt.
Hinzugefügt in Version 3.4.
Geändert in Version 3.8: Vor Version 3.8 war es notwendig, das Bit
Py_TPFLAGS_HAVE_FINALIZEzu setzen, damit dieses Feld verwendet werden konnte. Dies ist nicht mehr erforderlich.Siehe auch
PEP 442: „Safe object finalization“
Objektlebenszyklus für Details, wie dieser Slot mit anderen Slots zusammenhängt.
-
vectorcallfunc PyTypeObject.tp_vectorcall¶
Eine vectorcall-Funktion, die für Aufrufe dieses Typs (anstelle von Instanzen) verwendet wird. Mit anderen Worten,
tp_vectorcallkann verwendet werden, umtype.__call__zu optimieren, was typischerweise eine neue Instanz von *type* zurückgibt.Wie bei jeder vectorcall-Funktion wird, wenn
tp_vectorcallNULList, stattdessen das *tp_call*-Protokoll (Py_TYPE(type)->tp_call) verwendet.Hinweis
Das vectorcall-Protokoll erfordert, dass die vectorcall-Funktion das gleiche Verhalten wie die entsprechende
tp_callaufweist. Dies bedeutet, dasstype->tp_vectorcallmit dem Verhalten vonPy_TYPE(type)->tp_callübereinstimmen muss.Speziell, wenn *type* die Standard-Metaklasse verwendet, muss
type->tp_vectorcalldasselbe Verhalten aufweisen wie PyType_Type->tp_call, welcheruft
type->tp_newauf,wenn das Ergebnis eine Unterklasse von *type* ist, ruft
type->tp_initauf dem Ergebnis vontp_newauf undgibt das Ergebnis von
tp_newzurück.
Typischerweise wird
tp_vectorcallüberschrieben, um diesen Prozess für spezifischetp_newundtp_initzu optimieren. Achten Sie bei der Erstellung von für Benutzer untervererbbaren Typen darauf, dass beide überschrieben werden können (unter Verwendung von__new__()und__init__(), bzw.).Vererbung
Dieses Feld wird nie vererbt.
Hinzugefügt in Version 3.9: (Das Feld existiert seit 3.8, wird aber erst seit 3.9 verwendet)
-
unsigned char PyTypeObject.tp_watched¶
Intern. Nicht verwenden.
Hinzugefügt in Version 3.12.
Statische Typen¶
Traditionell sind in C-Code definierte Typen *statisch*, d.h. eine statische PyTypeObject-Struktur wird direkt im Code definiert und mit PyType_Ready() initialisiert.
Dies führt zu Typen, die im Vergleich zu in Python definierten Typen eingeschränkt sind
Statische Typen sind auf eine Basis beschränkt, d.h. sie können keine Mehrfachvererbung verwenden.
Statische Typobjekte (aber nicht unbedingt ihre Instanzen) sind unveränderlich. Es ist nicht möglich, die Attribute des Typobjekts von Python aus hinzuzufügen oder zu ändern.
Statische Typobjekte werden zwischen Sub-Interpretern geteilt, daher sollten sie keinen Sub-Interpreter-spezifischen Zustand enthalten.
Da PyTypeObject als undurchsichtige Struktur nur Teil der Limited API ist, müssen alle Erweiterungsmodule, die statische Typen verwenden, für eine bestimmte Python-Nebenversion kompiliert werden.
Heap-Typen¶
Eine Alternative zu statischen Typen sind *heap-allokierte Typen* oder kurz *Heap-Typen*, die Klassen, die mit der class-Anweisung von Python erstellt werden, eng entsprechen. Heap-Typen haben das Flag Py_TPFLAGS_HEAPTYPE gesetzt.
Dies geschieht durch Füllen einer PyType_Spec-Struktur und Aufrufen von PyType_FromSpec(), PyType_FromSpecWithBases(), PyType_FromModuleAndSpec() oder PyType_FromMetaclass().
Zahlenobjekt-Strukturen¶
-
type PyNumberMethods¶
Diese Struktur enthält Zeiger auf die Funktionen, die ein Objekt zur Implementierung des Zahlenprotokolls verwendet. Jede Funktion wird von der Funktion mit ähnlichem Namen verwendet, die im Abschnitt Number Protocol dokumentiert ist.
Hier ist die Strukturdefinition
typedef struct { binaryfunc nb_add; binaryfunc nb_subtract; binaryfunc nb_multiply; binaryfunc nb_remainder; binaryfunc nb_divmod; ternaryfunc nb_power; unaryfunc nb_negative; unaryfunc nb_positive; unaryfunc nb_absolute; inquiry nb_bool; unaryfunc nb_invert; binaryfunc nb_lshift; binaryfunc nb_rshift; binaryfunc nb_and; binaryfunc nb_xor; binaryfunc nb_or; unaryfunc nb_int; void *nb_reserved; unaryfunc nb_float; binaryfunc nb_inplace_add; binaryfunc nb_inplace_subtract; binaryfunc nb_inplace_multiply; binaryfunc nb_inplace_remainder; ternaryfunc nb_inplace_power; binaryfunc nb_inplace_lshift; binaryfunc nb_inplace_rshift; binaryfunc nb_inplace_and; binaryfunc nb_inplace_xor; binaryfunc nb_inplace_or; binaryfunc nb_floor_divide; binaryfunc nb_true_divide; binaryfunc nb_inplace_floor_divide; binaryfunc nb_inplace_true_divide; unaryfunc nb_index; binaryfunc nb_matrix_multiply; binaryfunc nb_inplace_matrix_multiply; } PyNumberMethods;
Hinweis
Binäre und ternäre Funktionen müssen den Typ aller ihrer Operanden überprüfen und die notwendigen Konvertierungen implementieren (mindestens einer der Operanden ist eine Instanz des definierten Typs). Wenn die Operation für die gegebenen Operanden nicht definiert ist, müssen binäre und ternäre Funktionen
Py_NotImplementedzurückgeben. Wenn ein anderer Fehler aufgetreten ist, müssen sieNULLzurückgeben und eine Ausnahme setzen.Hinweis
Das Feld
nb_reservedsollte immerNULLsein. Es hieß frühernb_longund wurde in Python 3.0.1 umbenannt.
-
binaryfunc PyNumberMethods.nb_add¶
-
binaryfunc PyNumberMethods.nb_subtract¶
-
binaryfunc PyNumberMethods.nb_multiply¶
-
binaryfunc PyNumberMethods.nb_remainder¶
-
binaryfunc PyNumberMethods.nb_divmod¶
-
ternaryfunc PyNumberMethods.nb_power¶
-
unaryfunc PyNumberMethods.nb_negative¶
-
unaryfunc PyNumberMethods.nb_positive¶
-
unaryfunc PyNumberMethods.nb_absolute¶
-
inquiry PyNumberMethods.nb_bool¶
-
unaryfunc PyNumberMethods.nb_invert¶
-
binaryfunc PyNumberMethods.nb_lshift¶
-
binaryfunc PyNumberMethods.nb_rshift¶
-
binaryfunc PyNumberMethods.nb_and¶
-
binaryfunc PyNumberMethods.nb_xor¶
-
binaryfunc PyNumberMethods.nb_or¶
-
unaryfunc PyNumberMethods.nb_int¶
-
void *PyNumberMethods.nb_reserved¶
-
unaryfunc PyNumberMethods.nb_float¶
-
binaryfunc PyNumberMethods.nb_inplace_add¶
-
binaryfunc PyNumberMethods.nb_inplace_subtract¶
-
binaryfunc PyNumberMethods.nb_inplace_multiply¶
-
binaryfunc PyNumberMethods.nb_inplace_remainder¶
-
ternaryfunc PyNumberMethods.nb_inplace_power¶
-
binaryfunc PyNumberMethods.nb_inplace_lshift¶
-
binaryfunc PyNumberMethods.nb_inplace_rshift¶
-
binaryfunc PyNumberMethods.nb_inplace_and¶
-
binaryfunc PyNumberMethods.nb_inplace_xor¶
-
binaryfunc PyNumberMethods.nb_inplace_or¶
-
binaryfunc PyNumberMethods.nb_floor_divide¶
-
binaryfunc PyNumberMethods.nb_true_divide¶
-
binaryfunc PyNumberMethods.nb_inplace_floor_divide¶
-
binaryfunc PyNumberMethods.nb_inplace_true_divide¶
-
unaryfunc PyNumberMethods.nb_index¶
-
binaryfunc PyNumberMethods.nb_matrix_multiply¶
-
binaryfunc PyNumberMethods.nb_inplace_matrix_multiply¶
Mapping-Objekt-Strukturen¶
-
type PyMappingMethods¶
Diese Struktur enthält Zeiger auf die Funktionen, die ein Objekt zur Implementierung des Mapping-Protokolls verwendet. Sie hat drei Member
-
lenfunc PyMappingMethods.mp_length¶
Diese Funktion wird von
PyMapping_Size()undPyObject_Size()verwendet und hat die gleiche Signatur. Dieses Feld kann aufNULLgesetzt werden, wenn das Objekt keine definierte Länge hat.
-
binaryfunc PyMappingMethods.mp_subscript¶
Diese Funktion wird von
PyObject_GetItem()undPySequence_GetSlice()verwendet und hat die gleiche Signatur wiePyObject_GetItem(). Dieses Feld muss gefüllt sein, damit die FunktionPyMapping_Check()1zurückgibt; andernfalls kann esNULLsein.
-
objobjargproc PyMappingMethods.mp_ass_subscript¶
Diese Funktion wird von
PyObject_SetItem(),PyObject_DelItem(),PySequence_SetSlice()undPySequence_DelSlice()verwendet. Sie hat die gleiche Signatur wiePyObject_SetItem(), aber *v* kann auch aufNULLgesetzt werden, um ein Element zu löschen. Wenn dieses FeldNULList, unterstützt das Objekt keine Elementzuweisung und -löschung.
Sequenzobjekt-Strukturen¶
-
type PySequenceMethods¶
Diese Struktur enthält Zeiger auf die Funktionen, die ein Objekt zur Implementierung des Sequenzprotokolls verwendet.
-
lenfunc PySequenceMethods.sq_length¶
Diese Funktion wird von
PySequence_Size()undPyObject_Size()verwendet und hat die gleiche Signatur. Sie wird auch zur Behandlung negativer Indizes über die Slotssq_itemundsq_ass_itemverwendet.
-
binaryfunc PySequenceMethods.sq_concat¶
Diese Funktion wird von
PySequence_Concat()verwendet und hat die gleiche Signatur. Sie wird auch vom Operator+verwendet, nachdem die numerische Addition über den Slotnb_addversucht wurde.
-
ssizeargfunc PySequenceMethods.sq_repeat¶
Diese Funktion wird von
PySequence_Repeat()verwendet und hat die gleiche Signatur. Sie wird auch vom Operator*verwendet, nachdem die numerische Multiplikation über den Slotnb_multiplyversucht wurde.
-
ssizeargfunc PySequenceMethods.sq_item¶
Diese Funktion wird von
PySequence_GetItem()verwendet und hat die gleiche Signatur. Sie wird auch vonPyObject_GetItem()verwendet, nachdem die Subskription über den Slotmp_subscriptversucht wurde. Dieses Feld muss gefüllt sein, damit die FunktionPySequence_Check()1zurückgibt; andernfalls kann esNULLsein.Negative Indizes werden wie folgt behandelt: Wenn der Slot
sq_lengthgefüllt ist, wird er aufgerufen und die Sequenzlänge wird zur Berechnung eines positiven Index verwendet, der ansq_itemübergeben wird. Wennsq_lengthNULList, wird der Index unverändert an die Funktion übergeben.
-
ssizeobjargproc PySequenceMethods.sq_ass_item¶
Diese Funktion wird von
PySequence_SetItem()verwendet und hat die gleiche Signatur. Sie wird auch vonPyObject_SetItem()undPyObject_DelItem()verwendet, nachdem der Artikelzuweisungs- und Löschversuch über denmp_ass_subscript-Slot versucht wurde. Dieser Slot kann aufNULLgesetzt werden, wenn das Objekt keine Elementzuweisung und -löschung unterstützt.
-
objobjproc PySequenceMethods.sq_contains¶
Diese Funktion kann von
PySequence_Contains()verwendet werden und hat die gleiche Signatur. Dieser Slot kann aufNULLgesetzt werden. In diesem Fall durchläuftPySequence_Contains()einfach die Sequenz, bis es eine Übereinstimmung findet.
-
binaryfunc PySequenceMethods.sq_inplace_concat¶
Diese Funktion wird von
PySequence_InPlaceConcat()verwendet und hat die gleiche Signatur. Sie sollte ihren ersten Operanden modifizieren und ihn zurückgeben. Dieser Slot kann aufNULLgesetzt werden. In diesem Fall greiftPySequence_InPlaceConcat()aufPySequence_Concat()zurück. Sie wird auch von der erweiterten Zuweisung+=verwendet, nachdem sie versucht hat, eine numerische In-Place-Addition über dennb_inplace_add-Slot durchzuführen.
-
ssizeargfunc PySequenceMethods.sq_inplace_repeat¶
Diese Funktion wird von
PySequence_InPlaceRepeat()verwendet und hat die gleiche Signatur. Sie sollte ihren ersten Operanden modifizieren und ihn zurückgeben. Dieser Slot kann aufNULLgesetzt werden. In diesem Fall greiftPySequence_InPlaceRepeat()aufPySequence_Repeat()zurück. Sie wird auch von der erweiterten Zuweisung*=verwendet, nachdem sie versucht hat, eine numerische In-Place-Multiplikation über dennb_inplace_multiply-Slot durchzuführen.
Buffer Object Structures¶
-
type PyBufferProcs¶
Diese Struktur enthält Zeiger auf die Funktionen, die vom Buffer-Protokoll benötigt werden. Das Protokoll definiert, wie ein Exporteur-Objekt seine internen Daten für Konsumenten-Objekte verfügbar machen kann.
-
getbufferproc PyBufferProcs.bf_getbuffer¶
Die Signatur dieser Funktion ist
int (PyObject *exporter, Py_buffer *view, int flags);
Behandelt eine Anfrage an den Exporter, die view gemäß den flags auszufüllen. Mit Ausnahme von Punkt (3) muss eine Implementierung dieser Funktion die folgenden Schritte ausführen:
Prüfen Sie, ob die Anfrage erfüllt werden kann. Wenn nicht, lösen Sie
BufferErroraus, setzen Sie view->obj aufNULLund geben Sie-1zurück.Füllen Sie die angeforderten Felder aus.
Inkrementieren Sie einen internen Zähler für die Anzahl der Exporte.
Setzen Sie view->obj auf exporter und inkrementieren Sie view->obj.
Geben Sie
0zurück.
Wenn exporter Teil einer Kette oder eines Baums von Puffer-Anbietern ist, können zwei Hauptschemata verwendet werden:
Re-Export: Jedes Mitglied des Baums fungiert als Exporteur-Objekt und setzt view->obj auf eine neue Referenz auf sich selbst.
Weiterleitung: Die Pufferanfrage wird an das Wurzelobjekt des Baums weitergeleitet. Hier wird view->obj eine neue Referenz auf das Wurzelobjekt sein.
Die einzelnen Felder von view sind im Abschnitt Buffer-Struktur beschrieben, die Regeln, wie ein Exporteur auf spezifische Anfragen reagieren muss, sind im Abschnitt Buffer-Anfragetypen aufgeführt.
Der gesamte Speicher, auf den in der Struktur
Py_bufferverwiesen wird, gehört dem Exporteur und muss gültig bleiben, solange keine Verbraucher mehr vorhanden sind.format,shape,strides,suboffsetsundinternalsind für den Verbraucher schreibgeschützt.PyBuffer_FillInfo()bietet eine einfache Möglichkeit, einen einfachen Byte-Puffer bereitzustellen und dabei korrekt mit allen Anfragetypen umzugehen.PyObject_GetBuffer()ist die Schnittstelle für den Konsumenten, die diese Funktion umschließt.
-
releasebufferproc PyBufferProcs.bf_releasebuffer¶
Die Signatur dieser Funktion ist
void (PyObject *exporter, Py_buffer *view);
Behandelt eine Anfrage zur Freigabe der Ressourcen des Puffers. Wenn keine Ressourcen freigegeben werden müssen, kann
PyBufferProcs.bf_releasebufferNULLsein. Andernfalls führt eine Standardimplementierung dieser Funktion die folgenden optionalen Schritte aus:Dekrementieren Sie einen internen Zähler für die Anzahl der Exporte.
Wenn der Zähler
0ist, geben Sie allen Speicher frei, der mit view verbunden ist.
Der Exporteur MUSS das Feld
internalverwenden, um Puffer-spezifische Ressourcen zu verfolgen. Dieses Feld bleibt garantiert konstant, während ein Verbraucher eine Kopie des ursprünglichen Puffers als view-Argument übergeben KANN.Diese Funktion darf view->obj NICHT dekrementieren, da dies automatisch in
PyBuffer_Release()geschieht (dieses Schema ist nützlich zum Brechen von Referenzzyklen).PyBuffer_Release()ist die Schnittstelle für den Konsumenten, die diese Funktion umschließt.
Async Object Structures¶
Hinzugefügt in Version 3.5.
-
type PyAsyncMethods¶
Diese Struktur enthält Zeiger auf die Funktionen, die zur Implementierung von awaitable und asynchronous iterator Objekten benötigt werden.
Hier ist die Strukturdefinition
typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; sendfunc am_send; } PyAsyncMethods;
-
unaryfunc PyAsyncMethods.am_await¶
Die Signatur dieser Funktion ist
PyObject *am_await(PyObject *self);
Das zurückgegebene Objekt muss ein Iterator sein, d.h.
PyIter_Check()muss1für dieses Objekt zurückgeben.Dieser Slot kann auf
NULLgesetzt werden, wenn ein Objekt kein awaitable ist.
-
unaryfunc PyAsyncMethods.am_aiter¶
Die Signatur dieser Funktion ist
PyObject *am_aiter(PyObject *self);
Muss ein asynchronous iterator-Objekt zurückgeben. Siehe
__anext__()für Details.Dieser Slot kann auf
NULLgesetzt werden, wenn ein Objekt das Protokoll für asynchrone Iteration nicht implementiert.
-
unaryfunc PyAsyncMethods.am_anext¶
Die Signatur dieser Funktion ist
PyObject *am_anext(PyObject *self);
Muss ein awaitable-Objekt zurückgeben. Siehe
__anext__()für Details. Dieser Slot kann aufNULLgesetzt werden.
-
sendfunc PyAsyncMethods.am_send¶
Die Signatur dieser Funktion ist
PySendResult am_send(PyObject *self, PyObject *arg, PyObject **result);
Siehe
PyIter_Send()für Details. Dieser Slot kann aufNULLgesetzt werden.Hinzugefügt in Version 3.10.
Slot Typ typedefs¶
-
typedef PyObject *(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems)¶
- Teil der Stable ABI.
Der Zweck dieser Funktion ist es, die Speicherzuweisung von der Speicherinitialisierung zu trennen. Sie sollte einen Zeiger auf einen Speicherblock ausreichender Länge für die Instanz zurückgeben, ordnungsgemäß ausgerichtet und auf Null initialisiert, aber mit
ob_refcntauf1undob_typeauf den Typ-Argument gesetzt. Wenn dietp_itemsizedes Typs ungleich Null ist, sollte das Feldob_sizedes Objekts auf nitems gesetzt und die Länge des zugewiesenen Speicherblockstp_basicsize + nitems*tp_itemsizebetragen, auf ein Vielfaches vonsizeof(void*)aufgerundet; andernfalls wird nitems nicht verwendet und die Länge des Blocks solltetp_basicsizesein.Diese Funktion sollte keine weitere Instanzinitialisierung durchführen, nicht einmal die Zuweisung von zusätzlichem Speicher; dies sollte von
tp_newübernommen werden.
-
typedef void (*destructor)(PyObject*)¶
- Teil der Stable ABI.
-
typedef PyObject *(*newfunc)(PyTypeObject*, PyObject*, PyObject*)¶
- Teil der Stable ABI.
Siehe
tp_new.
-
typedef PyObject *(*reprfunc)(PyObject*)¶
- Teil der Stable ABI.
Siehe
tp_repr.
-
typedef PyObject *(*getattrfunc)(PyObject *self, char *attr)¶
- Teil der Stable ABI.
Gibt den Wert des benannten Attributs für das Objekt zurück.
-
typedef int (*setattrfunc)(PyObject *self, char *attr, PyObject *value)¶
- Teil der Stable ABI.
Setzt den Wert des benannten Attributs für das Objekt. Das value-Argument wird auf
NULLgesetzt, um das Attribut zu löschen.
-
typedef PyObject *(*getattrofunc)(PyObject *self, PyObject *attr)¶
- Teil der Stable ABI.
Gibt den Wert des benannten Attributs für das Objekt zurück.
Siehe
tp_getattro.
-
typedef int (*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value)¶
- Teil der Stable ABI.
Setzt den Wert des benannten Attributs für das Objekt. Das value-Argument wird auf
NULLgesetzt, um das Attribut zu löschen.Siehe
tp_setattro.
-
typedef PyObject *(*descrgetfunc)(PyObject*, PyObject*, PyObject*)¶
- Teil der Stable ABI.
Siehe
tp_descr_get.
-
typedef int (*descrsetfunc)(PyObject*, PyObject*, PyObject*)¶
- Teil der Stable ABI.
Siehe
tp_descr_set.
-
typedef Py_hash_t (*hashfunc)(PyObject*)¶
- Teil der Stable ABI.
Siehe
tp_hash.
-
typedef PyObject *(*richcmpfunc)(PyObject*, PyObject*, int)¶
- Teil der Stable ABI.
Siehe
tp_richcompare.
-
typedef PyObject *(*getiterfunc)(PyObject*)¶
- Teil der Stable ABI.
Siehe
tp_iter.
-
typedef PyObject *(*iternextfunc)(PyObject*)¶
- Teil der Stable ABI.
Siehe
tp_iternext.
-
typedef Py_ssize_t (*lenfunc)(PyObject*)¶
- Teil der Stable ABI.
-
typedef int (*getbufferproc)(PyObject*, Py_buffer*, int)¶
- Teil der Stable ABI seit Version 3.12.
-
typedef void (*releasebufferproc)(PyObject*, Py_buffer*)¶
- Teil der Stable ABI seit Version 3.12.
-
typedef PyObject *(*unaryfunc)(PyObject*)¶
- Teil der Stable ABI.
-
typedef PyObject *(*binaryfunc)(PyObject*, PyObject*)¶
- Teil der Stable ABI.
-
typedef PyObject *(*ssizeargfunc)(PyObject*, Py_ssize_t)¶
- Teil der Stable ABI.
-
typedef int (*ssizeobjargproc)(PyObject*, Py_ssize_t, PyObject*)¶
- Teil der Stable ABI.
-
typedef int (*objobjproc)(PyObject*, PyObject*)¶
- Teil der Stable ABI.
-
typedef int (*objobjargproc)(PyObject*, PyObject*, PyObject*)¶
- Teil der Stable ABI.
Beispiele¶
Die folgenden sind einfache Beispiele für Python-Typdefinitionen. Sie beinhalten gängige Verwendungsmöglichkeiten, denen Sie begegnen können. Einige zeigen knifflige Grenzfälle. Für weitere Beispiele, praktische Informationen und ein Tutorial siehe Definieren von Erweiterungstypen: Tutorial und Definieren von Erweiterungstypen: Verschiedene Themen.
Ein einfacher statischer Typ
typedef struct {
PyObject_HEAD
const char *data;
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
.tp_basicsize = sizeof(MyObject),
.tp_doc = PyDoc_STR("My objects"),
.tp_new = myobj_new,
.tp_dealloc = (destructor)myobj_dealloc,
.tp_repr = (reprfunc)myobj_repr,
};
Möglicherweise finden Sie auch älteren Code (insbesondere im CPython-Codebasis) mit einem ausführlicheren Initialisierer
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"mymod.MyObject", /* tp_name */
sizeof(MyObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)myobj_dealloc, /* tp_dealloc */
0, /* tp_vectorcall_offset */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_async */
(reprfunc)myobj_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
0, /* tp_flags */
PyDoc_STR("My objects"), /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
myobj_new, /* tp_new */
};
Ein Typ, der schwache Referenzen, Instanz-Dicts und Hashing unterstützt
typedef struct {
PyObject_HEAD
const char *data;
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
.tp_basicsize = sizeof(MyObject),
.tp_doc = PyDoc_STR("My objects"),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT |
Py_TPFLAGS_MANAGED_WEAKREF,
.tp_new = myobj_new,
.tp_traverse = (traverseproc)myobj_traverse,
.tp_clear = (inquiry)myobj_clear,
.tp_alloc = PyType_GenericNew,
.tp_dealloc = (destructor)myobj_dealloc,
.tp_repr = (reprfunc)myobj_repr,
.tp_hash = (hashfunc)myobj_hash,
.tp_richcompare = PyBaseObject_Type.tp_richcompare,
};
Eine Zeichenketten-Unterklasse, die nicht unterklassifiziert werden kann und nicht zum Erstellen von Instanzen aufgerufen werden kann (z.B. verwendet eine separate Factory-Funktion) unter Verwendung des Flags Py_TPFLAGS_DISALLOW_INSTANTIATION
typedef struct {
PyUnicodeObject raw;
char *extra;
} MyStr;
static PyTypeObject MyStr_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyStr",
.tp_basicsize = sizeof(MyStr),
.tp_base = NULL, // set to &PyUnicode_Type in module init
.tp_doc = PyDoc_STR("my custom str"),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
.tp_repr = (reprfunc)myobj_repr,
};
Der einfachste statische Typ mit Instanzen fester Länge
typedef struct {
PyObject_HEAD
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
};
Der einfachste statische Typ mit Instanzen variabler Länge
typedef struct {
PyObject_VAR_HEAD
const char *data[1];
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
.tp_basicsize = sizeof(MyObject) - sizeof(char *),
.tp_itemsize = sizeof(char *),
};