Typobjekt-Strukturen¶
Eine der wichtigsten Strukturen des Python-Objektsystems ist vielleicht die Struktur, die einen neuen Typ festlegt: die Struktur PyTypeObject. Typobjekte lassen sich mit allen PyObject_*- oder PyType_*-Funktionen behandeln, bieten den meisten Python-Anwendungen aber wenig Interessantes. Diese Objekte sind grundlegend dafür, wie Objekte sich verhalten, und deshalb für den Interpreter selbst und für jedes Erweiterungsmodul, das neue Typen umsetzt, 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, überwiegend C-Funktionszeiger, von denen jeder einen kleinen Teil der Funktionalität des Typs umsetzt. Die Felder des Typobjekts werden in diesem Abschnitt im Einzelnen untersucht. Sie werden in der Reihenfolge beschrieben, in der sie in der Struktur vorkommen.
Zusätzlich zur folgenden Kurzübersicht bietet der Abschnitt Beispiele einen schnellen Einblick in Bedeutung und Verwendung von PyTypeObject.
Kurzübersicht¶
„tp-Slots“¶
PyTypeObject-Slot [1] |
Spezialmethoden/-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 |
Spezialmethoden |
|
|---|---|---|
__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 |
Parametertypen |
Rückgabetyp |
|---|---|---|
|
||
|
void |
|
void * |
void |
|
int |
||
|
||
int |
||
|
|
|
PyObject *const char *
|
|
|
int |
||
|
||
int |
||
|
||
int |
||
|
Py_hash_t |
|
|
||
|
|
|
|
|
|
|
||
int |
||
void |
||
|
int |
|
PyObject * |
|
|
|
||
|
||
|
||
int |
||
int |
||
int |
Mehr dazu steht unten unter Typedefs für Slot-Typen.
Definition von PyTypeObject¶
Die Strukturdefinition für PyTypeObject steht in Include/cpython/object.h. Der Bequemlichkeit halber ist sie hier 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 Struktur des Typobjekts erweitert die Struktur PyVarObject. Das Feld ob_size wird für dynamische Typen verwendet (erzeugt von type_new(), üblicherweise aus einer class-Anweisung heraus aufgerufen). Beachte, dass PyType_Type (der Metatyp) tp_itemsize initialisiert, was bedeutet, dass seine Instanzen (also Typobjekte) das Feld ob_size haben müssen.
Der Referenzzähler des Typobjekts wird vom Makro
PyObject_HEAD_INITauf1initialisiert. Beachte, dass bei statisch angelegten Typobjekten die Instanzen des Typs (Objekte, derenob_typeauf den Typ zurückverweist) nicht als Referenzen zählen. Bei dynamisch angelegten Typobjekten zählen die Instanzen dagegen sehr wohl als Referenzen.Vererbung:
Dieses Feld wird nicht an Untertypen vererbt.
Das ist der Typ des Typs, mit anderen Worten sein Metatyp. Er wird durch das Argument des Makros
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 allerdings, dass das kein gültiger Initialisierer sei. Deshalb ist es üblich, dem MakroPyObject_HEAD_INITNULLzu übergeben und dieses Feld ausdrücklich am Anfang der Initialisierungsfunktion des Moduls zu setzen, bevor irgendetwas anderes geschieht. Üblicherweise sieht das so aus:Foo_Type.ob_type = &PyType_Type;Das sollte geschehen, bevor Instanzen des Typs erzeugt 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 an Untertypen vererbt.
PyVarObject-Slots¶
Bei statisch angelegten Typobjekten sollte das auf null initialisiert werden. Bei dynamisch angelegten Typobjekten hat dieses Feld eine besondere interne Bedeutung.
Auf dieses Feld sollte über das Makro
Py_SIZE()zugegriffen werden.Vererbung:
Dieses Feld wird nicht an Untertypen vererbt.
PyTypeObject-Slots¶
Zu jedem Slot gibt es einen Abschnitt, der die Vererbung beschreibt. Kann PyType_Ready() einen Wert setzen, wenn das Feld auf NULL gesetzt ist, gibt es außerdem einen Abschnitt „Vorgabe“. (Beachte, dass viele Felder, die an PyBaseObject_Type und PyType_Type gesetzt sind, praktisch wie Vorgaben wirken.)
-
const char *PyTypeObject.tp_name¶
Die zugehörige
Slot-IDsteht unterPy_tp_name.Zeiger auf eine NUL-terminierte Zeichenkette mit dem Namen des Typs. Bei Typen, die als Modulglobale zugänglich sind, sollte die Zeichenkette der vollständige Modulname sein, gefolgt von einem Punkt und dem Typnamen. Bei integrierten Typen sollte es nur der Typname sein. Ist das Modul ein Untermodul eines Pakets, gehört der vollständige Paketname zum vollständigen Modulnamen. Ein Typ namens
Tzum Beispiel, der im ModulMim UnterpaketQim PaketPdefiniert ist, sollte dentp_name-Initialisierer"P.Q.M.T"haben.Bei dynamisch angelegten Typobjekten sollte das nur der Typname sein. Der Modulname wird ausdrücklich im Dictionary des Typs unter dem Schlüssel
'__module__'abgelegt.Bei statisch angelegten Typobjekten sollte das Feld tp_name einen Punkt enthalten. Alles vor dem letzten Punkt wird als Attribut
__module__zugänglich gemacht, alles nach dem letzten Punkt als Attribut__name__.Ist kein Punkt vorhanden, wird das gesamte Feld
tp_nameals Attribut__name__zugänglich gemacht, und das Attribut__module__ist undefiniert (sofern es nicht wie oben beschrieben ausdrücklich im Dictionary gesetzt wird). Das bedeutet, dass sich dein Typ nicht mit pickle serialisieren lässt. Außerdem wird er in Moduldokumentationen, die mit pydoc erzeugt werden, nicht aufgeführt.Dieses Feld darf nicht
NULLsein. Es ist das einzige erforderliche Feld inPyTypeObject()(abgesehen möglicherweise vontp_itemsize).Vererbung:
Dieses Feld wird nicht an Untertypen vererbt.
-
Py_ssize_t PyTypeObject.tp_basicsize¶
-
Py_ssize_t PyTypeObject.tp_itemsize¶
Über diese Felder lässt sich die Größe von Instanzen des Typs in Bytes berechnen.
Die zugehörigen
Slot-IDsstehen unterPy_tp_basicsize,Py_tp_extra_basicsizeundPy_tp_itemsize.Es gibt zwei Arten von Typen: Typen mit Instanzen fester Länge haben ein Feld
tp_itemsizevon null, Typen mit Instanzen veränderlicher Länge ein Feldtp_itemsizeungleich null. Bei einem Typ mit Instanzen fester Länge haben alle Instanzen dieselbe Größe, die intp_basicsizeangegeben ist. (Ausnahmen von dieser Regel lassen sich mitPyUnstable_Object_GC_NewWithExtraData()machen.)Bei einem Typ mit Instanzen veränderlicher Länge 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 legen ihn im Feldob_sizeder Instanz ab. Beachte, dass das Feldob_sizespäter für andere Zwecke verwendet werden kann.int-Instanzen zum Beispiel nutzen die Bits vonob_sizeauf eine von der Implementierung festgelegte Weise. Auf den zugrunde liegenden Speicher und seine Größe sollte überPyLong_Export()zugegriffen werden.Bemerkung
Auf das Feld
ob_sizesollte über die MakrosPy_SIZE()undPy_SET_SIZE()zugegriffen werden.Umgekehrt bedeutet das Vorhandensein eines Feldes
ob_sizeim Aufbau der Instanz nicht, dass die Instanzstruktur veränderliche Länge hat. Der Typlistzum Beispiel hat Instanzen fester Länge, und diese Instanzen haben trotzdem ein Feldob_size. (Wie beiintsolltest duob_sizevon Listen nicht unmittelbar auslesen. Rufe stattdessenPyList_Size()auf.)tp_basicsizeschließt den Platz ein, der für die Daten destp_basedes Typs nötig ist, zuzüglich aller zusätzlichen Daten, die jede Instanz braucht.Der richtige Weg,
tp_basicsizezu setzen, führt über densizeof-Operator auf der Struktur, mit der der Aufbau der Instanz deklariert wird. Diese Struktur muss die Struktur einschließen, mit der der Basistyp deklariert wird. Mit anderen Worten musstp_basicsizegrößer oder gleich demtp_basicsizedes Basistyps sein.Da jeder Typ ein Untertyp von
objectist, muss diese StrukturPyObjectoderPyVarObjecteinschließen (je nachdem, obob_sizeenthalten sein soll). Üblicherweise werden diese über das MakroPyObject_HEADbeziehungsweisePyObject_VAR_HEADfestgelegt.Die Grundgröße schließt die Größe des GC-Kopfes nicht ein, weil dieser Kopf nicht zu
PyObject_HEADgehört.Für Fälle, in denen die Struktur zur Deklaration des Basistyps unbekannt ist, siehe
PyType_Spec.basicsizeundPyType_FromMetaclass().Hinweise zur Ausrichtung:
tp_basicsizemuss ein Vielfaches von_Alignof(PyObject)sein. Verwendest du wie empfohlensizeofauf einerstruct, diePyObject_HEADeinschließt, sorgt der Compiler dafür. Verwendest du keine C-structoder Compiler-Erweiterungen wie__attribute__((packed)), liegt es an dir.Erfordern die veränderlichen Elemente eine bestimmte Ausrichtung, müssen
tp_basicsizeundtp_itemsizejeweils ein Vielfaches dieser Ausrichtung sein. Speichert der veränderliche Teil eines Typs zum Beispiel eindouble, liegt es in deiner Verantwortung, dass beide Felder ein Vielfaches von_Alignof(double)sind.
Vererbung:
Diese Felder werden von Untertypen einzeln vererbt. (Das heißt: Ist das Feld auf null gesetzt, kopiert
PyType_Ready()den Wert aus dem Basistyp, was anzeigt, dass die Instanzen keinen zusätzlichen Speicher brauchen.)Hat der Basistyp ein
tp_itemsizeungleich null, ist es im Allgemeinen nicht gefahrlos möglich,tp_itemsizein einem Untertyp auf einen anderen Wert ungleich null zu setzen (das hängt allerdings von der Umsetzung des Basistyps ab).
-
destructor PyTypeObject.tp_dealloc¶
The corresponding slot ID
Py_tp_deallocis part of the Stable ABI.Ein Zeiger auf die Destruktorfunktion der Instanz. Die Signatur der Funktion lautet:
void tp_dealloc(PyObject *self);
Die Destruktorfunktion sollte alle Referenzen entfernen, die die Instanz besitzt (also zum Beispiel
Py_CLEAR()aufrufen), alle Speicherpuffer freigeben, die der Instanz gehören, und die Funktiontp_freedes Typs aufrufen, um das Objekt selbst freizugeben.Rufst du möglicherweise Funktionen auf, die den Fehlerindikator setzen können, musst du
PyErr_GetRaisedException()undPyErr_SetRaisedException()verwenden, damit du einen bereits vorhandenen Fehlerindikator nicht überschreibst (die Freigabe könnte während der Behandlung eines anderen Fehlers erfolgt sein):static void foo_dealloc(foo_object *self) { PyObject *et, *ev, *etb; PyObject *exc = PyErr_GetRaisedException(); ... PyErr_SetRaisedException(exc); }
Der Dealloc-Handler selbst darf keine Ausnahme auslösen. Stößt er auf einen Fehlerfall, sollte er
PyErr_FormatUnraisable()aufrufen, um eine nicht auslösbare Ausnahme zu protokollieren (und zu löschen).Darüber, wann ein Objekt zerstört wird, werden keine Zusagen gemacht, außer:
Python zerstört ein Objekt sofort oder einige Zeit, nachdem die letzte Referenz darauf gelöscht wurde, sofern nicht sein Finalisierer (
tp_finalize) das Objekt anschließend wieder auferstehen lässt.Ein Objekt wird nicht zerstört, während es automatisch finalisiert (
tp_finalize) oder automatisch geleert wird (tp_clear).
CPython zerstört ein Objekt derzeit unmittelbar aus
Py_DECREF()heraus, sobald der neue Referenzzähler null ist. Das kann sich in einer künftigen Version ändern.Es wird empfohlen, am Anfang von
tp_deallocPyObject_CallFinalizerFromDealloc()aufzurufen, damit das Objekt vor der Zerstörung in jedem Fall finalisiert ist.Unterstützt der Typ die Speicherbereinigung (das Flag
Py_TPFLAGS_HAVE_GCist gesetzt), sollte der DestruktorPyObject_GC_UnTrack()aufrufen, bevor er Member-Felder leert.Es ist zulässig,
tp_clearaustp_deallocheraus aufzurufen, um doppelten Code zu vermeiden und sicherzustellen, dass das Objekt vor der Zerstörung immer geleert ist. Sei dir bewusst, dasstp_clearbereits aufgerufen worden sein kann.Ist der Typ auf dem Heap angelegt (
Py_TPFLAGS_HEAPTYPE), sollte der Deallokator die gehaltene Referenz auf sein Typobjekt freigeben (überPy_DECREF()), nachdem er den Deallokator des Typs aufgerufen hat. Siehe den Beispielcode unten.: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. Muss es etwas aufrufen, das eine Ausnahme auslösen könnte, ist der Ausnahmezustand zuerst zu sichern und später wiederherzustellen (nachdem etwaige 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_deallocdarf aus jedem Python-Thread aufgerufen werden, nicht nur aus dem, der das Objekt erzeugt hat (wird das Objekt Teil eines Referenzzyklus, kann dieser Zyklus von einer Speicherbereinigung in einem beliebigen Thread eingesammelt werden). Für Aufrufe der Python-API ist das kein Problem, denn der Thread, auf demtp_deallocaufgerufen wird, hat einen angehängten Thread-Zustand. Zerstört das zu zerstörende Objekt seinerseits Objekte aus einer anderen C-Bibliothek, ist allerdings darauf zu achten, dass das Zerstören dieser Objekte auf dem Thread, dertp_deallocaufgerufen hat, keine Annahmen dieser Bibliothek verletzt.Vererbung:
Dieses Feld wird an Untertypen vererbt.
Siehe auch
Object Life Cycle – Einzelheiten dazu, wie dieser Slot mit den anderen Slots zusammenhängt.
-
Py_ssize_t PyTypeObject.tp_vectorcall_offset¶
Ein wahlfreier Versatz zu einer Funktion je Instanz, die das Aufrufen des Objekts über das vectorcall-Protokoll umsetzt – eine wirksamere Alternative zum einfacheren
tp_call.Dieses Feld wird nur verwendet, wenn das Flag
Py_TPFLAGS_HAVE_VECTORCALLgesetzt ist. Ist es das, muss dies eine positive ganze Zahl sein, die den Versatz einesvectorcallfunc-Zeigers in der Instanz enthält.Der vectorcallfunc-Zeiger darf
NULLsein. Die Instanz verhält sich dann so, als wärePy_TPFLAGS_HAVE_VECTORCALLnicht gesetzt: Das Aufrufen der Instanz fällt auftp_callzurück.Jede Klasse, die
Py_TPFLAGS_HAVE_VECTORCALLsetzt, muss auchtp_callsetzen und dafür sorgen, dass dessen Verhalten zur vectorcallfunc-Funktion passt. Das lässt sich erreichen, indem tp_call aufPyVectorcall_Call()gesetzt wird.Geändert in Version 3.8: Vor Version 3.8 hieß dieser Slot
tp_print. In Python 2.x diente er der Ausgabe in eine Datei. In Python 3.0 bis 3.7 war er unbenutzt.Geändert in Version 3.12: Vor Version 3.12 war es nicht empfohlen, dass veränderliche Heap-Typen das vectorcall-Protokoll umsetzen. Setzt jemand
__call__in Python-Code, wird nur tp_call aktualisiert, womit es wahrscheinlich nicht mehr zur vectorcall-Funktion passt. Seit 3.12 schaltet das Setzen von__call__die vectorcall-Optimierung ab, indem es das FlagPy_TPFLAGS_HAVE_VECTORCALLlöscht.Vererbung:
Dieses Feld wird immer vererbt. Das Flag
Py_TPFLAGS_HAVE_VECTORCALLwird allerdings nicht immer vererbt. Ist es nicht gesetzt, verwendet die Unterklasse vectorcall nicht, außer wennPyVectorcall_Call()ausdrücklich aufgerufen wird.
-
getattrfunc PyTypeObject.tp_getattr¶
The corresponding slot ID
Py_tp_getattris part of the Stable ABI.Ein wahlfreier Zeiger auf die Funktion zum Lesen eines Attributs über eine Zeichenkette.
Dieses Feld ist veraltet. Ist es festgelegt, sollte es auf eine Funktion zeigen, die sich genauso verhält wie die Funktion
tp_getattro, aber eine C-Zeichenkette statt eines Python-Zeichenkettenobjekts für den Attributnamen nimmt.Vererbung:
Gruppe:
tp_getattr,tp_getattroDieses Feld wird von Untertypen gemeinsam mit
tp_getattrovererbt: Ein Untertyp erbt sowohltp_getattrals auchtp_getattrovon seinem Basistyp, wenntp_getattrundtp_getattrodes Untertyps beideNULLsind.
-
setattrfunc PyTypeObject.tp_setattr¶
The corresponding slot ID
Py_tp_setattris part of the Stable ABI.Ein wahlfreier Zeiger auf die Funktion zum Setzen und Löschen von Attributen.
Dieses Feld ist veraltet. Ist es festgelegt, sollte es auf eine Funktion zeigen, die sich genauso verhält wie die Funktion
tp_setattro, aber eine C-Zeichenkette statt eines Python-Zeichenkettenobjekts für den Attributnamen nimmt.Vererbung:
Gruppe:
tp_setattr,tp_setattroDieses Feld wird von Untertypen gemeinsam mit
tp_setattrovererbt: Ein Untertyp erbt sowohltp_setattrals auchtp_setattrovon seinem Basistyp, wenntp_setattrundtp_setattrodes Untertyps beideNULLsind.
-
PyAsyncMethods *PyTypeObject.tp_as_async¶
Zeiger auf eine zusätzliche Struktur mit Feldern, die nur für Objekte von Bedeutung sind, die die Protokolle abwartbar und asynchroner Iterator auf C-Ebene umsetzen. Einzelheiten stehen unter Strukturen für Async-Objekte.
Added in version 3.5: Früher bekannt als
tp_compareundtp_reserved.Vererbung:
Das Feld
tp_as_asyncwird nicht vererbt, die enthaltenen Felder werden aber einzeln vererbt.
-
reprfunc PyTypeObject.tp_repr¶
The corresponding slot ID
Py_tp_repris part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion, die die integrierte Funktion
repr()umsetzt.Die Signatur ist dieselbe wie bei
PyObject_Repr():PyObject *tp_repr(PyObject *self);
Die Funktion muss eine Zeichenkette oder ein Unicode-Objekt zurückgeben. Im Idealfall sollte sie eine Zeichenkette zurückgeben, die – an
eval()übergeben und in einer passenden Umgebung – ein Objekt mit demselben Wert ergibt. Ist das nicht machbar, sollte sie eine Zeichenkette zurückgeben, die mit'<'beginnt und mit'>'endet und aus der sich sowohl der Typ als auch der Wert des Objekts ableiten lassen.Vererbung:
Dieses Feld wird an Untertypen vererbt.
Vorgabe:
Ist dieses Feld nicht gesetzt, 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 mit Feldern, die nur für Objekte von Bedeutung sind, die das Zahlenprotokoll umsetzen. Diese Felder sind unter Strukturen für Zahlenobjekte dokumentiert.
Vererbung:
Das Feld
tp_as_numberwird nicht vererbt, die enthaltenen Felder werden aber einzeln vererbt.
-
PySequenceMethods *PyTypeObject.tp_as_sequence¶
Zeiger auf eine zusätzliche Struktur mit Feldern, die nur für Objekte von Bedeutung sind, die das Sequenzprotokoll umsetzen. Diese Felder sind unter Strukturen für Sequenzobjekte dokumentiert.
Vererbung:
Das Feld
tp_as_sequencewird nicht vererbt, die enthaltenen Felder werden aber einzeln vererbt.
-
PyMappingMethods *PyTypeObject.tp_as_mapping¶
Zeiger auf eine zusätzliche Struktur mit Feldern, die nur für Objekte von Bedeutung sind, die das Mapping-Protokoll umsetzen. Diese Felder sind unter Strukturen für Mapping-Objekte dokumentiert.
Vererbung:
Das Feld
tp_as_mappingwird nicht vererbt, die enthaltenen Felder werden aber einzeln vererbt.
-
hashfunc PyTypeObject.tp_hash¶
The corresponding slot ID
Py_tp_hashis part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion, die die integrierte Funktion
hash()umsetzt.Die Signatur ist dieselbe wie bei
PyObject_Hash():Py_hash_t tp_hash(PyObject *);
Der Wert
-1sollte nicht als gewöhnlicher Rückgabewert verwendet werden. Tritt bei der Berechnung des Hash-Werts ein Fehler auf, sollte die Funktion eine Ausnahme setzen und-1zurückgeben.Ist dieses Feld nicht gesetzt (und
tp_richcompareebenfalls nicht), löst der Versuch, den Hash des Objekts zu bilden, einTypeErroraus. Das entspricht dem Setzen aufPyObject_HashNotImplemented().Dieses Feld lässt sich ausdrücklich auf
PyObject_HashNotImplemented()setzen, um das Erben der hash-Methode von einem übergeordneten Typ zu unterbinden. Das wird als Entsprechung zu__hash__ = Noneauf Python-Ebene ausgelegt und führt dazu, dassisinstance(o, collections.Hashable)richtigerweiseFalsezurückgibt. Beachte, dass auch die Umkehrung gilt:__hash__ = Noneauf Python-Ebene an einer Klasse zu setzen führt dazu, dass der Slottp_hashaufPyObject_HashNotImplemented()gesetzt wird.Vererbung:
Gruppe:
tp_hash,tp_richcompareDieses Feld wird von Untertypen gemeinsam mit
tp_richcomparevererbt: Ein Untertyp erbt sowohltp_richcompareals auchtp_hash, wenntp_richcompareundtp_hashdes Untertyps beideNULLsind.Vorgabe:
PyBaseObject_TypeverwendetPyObject_GenericHash().
-
ternaryfunc PyTypeObject.tp_call¶
The corresponding slot ID
Py_tp_callis part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion, die das Aufrufen des Objekts umsetzt. Ist das Objekt nicht aufrufbar, sollte dies
NULLsein. Die Signatur ist dieselbe wie beiPyObject_Call():PyObject *tp_call(PyObject *self, PyObject *args, PyObject *kwargs);
Vererbung:
Dieses Feld wird an Untertypen vererbt.
-
reprfunc PyTypeObject.tp_str¶
The corresponding slot ID
Py_tp_stris part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion, die den integrierten Vorgang
str()umsetzt. (Beachte, dassstrinzwischen ein Typ ist undstr()den Konstruktor dieses Typs aufruft. Dieser Konstruktor ruftPyObject_Str()auf, um die eigentliche Arbeit zu erledigen, undPyObject_Str()ruft diesen Handler auf.)Die Signatur ist dieselbe wie bei
PyObject_Str():PyObject *tp_str(PyObject *self);
Die Funktion muss eine Zeichenkette oder ein Unicode-Objekt zurückgeben. Sie sollte eine „freundliche“ Textdarstellung des Objekts sein, denn das ist die Darstellung, die unter anderem die Funktion
print()verwendet.Vererbung:
Dieses Feld wird an Untertypen vererbt.
Vorgabe:
Ist dieses Feld nicht gesetzt, wird
PyObject_Repr()aufgerufen, um eine Textdarstellung zurückzugeben.
-
getattrofunc PyTypeObject.tp_getattro¶
The corresponding slot ID
Py_tp_getattrois part of the Stable ABI.Ein wahlfreier Zeiger auf die Funktion zum Lesen eines Attributs.
Die Signatur ist dieselbe wie bei
PyObject_GetAttr():PyObject *tp_getattro(PyObject *self, PyObject *attr);
Üblicherweise ist es praktisch, dieses Feld auf
PyObject_GenericGetAttr()zu setzen, was die gewöhnliche Art umsetzt, Objektattribute nachzuschlagen.Vererbung:
Gruppe:
tp_getattr,tp_getattroDieses Feld wird von Untertypen gemeinsam mit
tp_getattrvererbt: Ein Untertyp erbt sowohltp_getattrals auchtp_getattrovon seinem Basistyp, wenntp_getattrundtp_getattrodes Untertyps beideNULLsind.Vorgabe:
PyBaseObject_TypeverwendetPyObject_GenericGetAttr().
-
setattrofunc PyTypeObject.tp_setattro¶
The corresponding slot ID
Py_tp_setattrois part of the Stable ABI.Ein wahlfreier Zeiger auf die Funktion zum Setzen und Löschen von Attributen.
Die Signatur ist dieselbe wie bei
PyObject_SetAttr():int tp_setattro(PyObject *self, PyObject *attr, PyObject *value);
Außerdem muss unterstützt werden, dass value auf
NULLgesetzt wird, um ein Attribut zu löschen. Üblicherweise ist es praktisch, dieses Feld aufPyObject_GenericSetAttr()zu setzen, was die gewöhnliche Art umsetzt, Objektattribute zu setzen.Vererbung:
Gruppe:
tp_setattr,tp_setattroDieses Feld wird von Untertypen gemeinsam mit
tp_setattrvererbt: Ein Untertyp erbt sowohltp_setattrals auchtp_setattrovon seinem Basistyp, wenntp_setattrundtp_setattrodes Untertyps beideNULLsind.Vorgabe:
PyBaseObject_TypeverwendetPyObject_GenericSetAttr().
-
PyBufferProcs *PyTypeObject.tp_as_buffer¶
Zeiger auf eine zusätzliche Struktur mit Feldern, die nur für Objekte von Bedeutung sind, die die Puffer-Schnittstelle umsetzen. Diese Felder sind unter Strukturen für Pufferobjekte dokumentiert.
Vererbung:
Das Feld
tp_as_bufferwird nicht vererbt, die enthaltenen Felder werden aber einzeln vererbt.
-
unsigned long PyTypeObject.tp_flags¶
Die zugehörige
Slot-IDsteht unterPy_tp_flags.Dieses Feld ist eine Bitmaske verschiedener Flags. Manche Flags zeigen abweichendes Verhalten in bestimmten Situationen an, andere zeigen an, dass bestimmte Felder im Typobjekt (oder in den über
tp_as_number,tp_as_sequence,tp_as_mappingundtp_as_bufferreferenzierten Erweiterungsstrukturen), die früher nicht immer vorhanden waren, gültig sind. Ist ein solches Flag-Bit nicht gesetzt, darf auf die Typfelder, die es absichert, nicht zugegriffen werden. Sie sind stattdessen als null oderNULLzu betrachten.Vererbung:
Die Vererbung dieses Feldes ist kompliziert. Die meisten Flag-Bits werden einzeln vererbt, das heißt: Ist ein Flag-Bit im Basistyp gesetzt, erbt der Untertyp dieses Flag-Bit. Die Flag-Bits, die Erweiterungsstrukturen betreffen, werden streng dann vererbt, wenn die Erweiterungsstruktur vererbt wird, das heißt: Der Wert des Flag-Bits im Basistyp wird zusammen mit einem Zeiger auf die Erweiterungsstruktur in den Untertyp kopiert. Das Flag-Bit
Py_TPFLAGS_HAVE_GCwird gemeinsam mit den Felderntp_traverseundtp_clearvererbt, also dann, wenn das Flag-BitPy_TPFLAGS_HAVE_GCim Untertyp nicht gesetzt ist und die Feldertp_traverseundtp_clearim Untertyp vorhanden sind undNULL-Werte haben.Vorgabe:
PyBaseObject_TypeverwendetPy_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE.Bitmasken:
Derzeit sind die folgenden Bitmasken festgelegt. Sie lassen sich über den Operator
|miteinander verodern, um den Wert des Feldestp_flagszu bilden. Das MakroPyType_HasFeature()nimmt einen Typ und einen Flag-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 angelegt ist, zum Beispiel bei Typen, die dynamisch über
PyType_FromSpec()erzeugt werden. In diesem Fall gilt das Feldob_typeseiner Instanzen als Referenz auf den Typ, und das Typobjekt wird mit INCREF versehen, wenn eine neue Instanz erzeugt wird, und mit DECREF, wenn eine Instanz zerstört wird (das gilt nicht für Instanzen von Untertypen, sondern nur für den Typ, auf den das ob_type der Instanz verweist, bekommt INCREF oder DECREF). Heap-Typen sollten außerdem die Speicherbereinigung unterstützen, da sie mit ihrem eigenen Modulobjekt einen Referenzzyklus bilden können.Vererbung:
???
-
Py_TPFLAGS_BASETYPE¶
- Teil der Stable ABI.
Dieses Bit ist gesetzt, wenn der Typ als Basistyp eines anderen Typs verwendet werden kann. Ist dieses Bit nicht gesetzt, lässt sich vom Typ keine Unterklasse bilden (ähnlich einer „final“-Klasse in Java).
Vererbung:
???
-
Py_TPFLAGS_READY¶
Dieses Bit ist gesetzt, wenn das Typobjekt von
PyType_Ready()vollständig initialisiert wurde.Vererbung:
???
-
Py_TPFLAGS_READYING¶
Dieses Bit ist gesetzt, während
PyType_Ready()das Typobjekt gerade initialisiert.Vererbung:
???
-
Py_TPFLAGS_HAVE_GC¶
- Teil der Stable ABI.
Dieses Bit ist gesetzt, wenn das Objekt die Speicherbereinigung unterstützt. Ist dieses Bit gesetzt, muss Speicher für neue Instanzen (siehe
tp_alloc) überPyObject_GC_NewoderPyType_GenericAlloc()angefordert und (siehetp_free) überPyObject_GC_Del()freigegeben werden. Mehr dazu im Abschnitt Supporting Cyclic Garbage Collection.Vererbung:
Gruppe:
Py_TPFLAGS_HAVE_GC,tp_traverse,tp_clearDas Flag-Bit
Py_TPFLAGS_HAVE_GCwird gemeinsam mit den Felderntp_traverseundtp_clearvererbt, also dann, wenn das Flag-BitPy_TPFLAGS_HAVE_GCim Untertyp nicht gesetzt ist und die Feldertp_traverseundtp_clearim Untertyp vorhanden sind undNULL-Werte haben.
-
Py_TPFLAGS_DEFAULT¶
- Teil der Stable ABI.
Das ist eine Bitmaske aller Bits, die das Vorhandensein bestimmter Felder im Typobjekt und seinen Erweiterungsstrukturen betreffen. Derzeit umfasst sie die folgenden Bits:
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION.Vererbung:
???
-
Py_TPFLAGS_METHOD_DESCRIPTOR¶
- Teil der Stable ABI seit Version 3.8.
Dieses Bit zeigt an, dass Objekte sich wie ungebundene Methoden verhalten.
Ist dieses Flag für
type(meth)gesetzt, gilt:meth.__get__(obj, cls)(*args, **kwds)(mitobjnicht None) muss gleichbedeutend sein mitmeth(obj, *args, **kwds).meth.__get__(None, cls)(*args, **kwds)muss gleichbedeutend sein mitmeth(*args, **kwds).
Dieses Flag ermöglicht eine Optimierung für typische Methodenaufrufe wie
obj.meth(): Es vermeidet, fürobj.methein vorübergehendes Objekt für die „gebundene Methode“ zu erzeugen.Added in version 3.8.
Vererbung:
Dieses Flag wird nie an Typen vererbt, bei denen das Flag
Py_TPFLAGS_IMMUTABLETYPEnicht gesetzt ist. Bei Erweiterungstypen wird es immer dann vererbt, wenntp_descr_getvererbt wird.
-
Py_TPFLAGS_MANAGED_DICT¶
Dieses Bit zeigt an, dass Instanzen der Klasse ein Attribut
__dict__haben und dass die VM den Platz für das Dictionary verwaltet.Ist dieses Flag gesetzt, muss auch
Py_TPFLAGS_HAVE_GCgesetzt sein.Die traverse-Funktion des Typs muss
PyObject_VisitManagedDict()aufrufen und seine clear-FunktionPyObject_ClearManagedDict().Added in version 3.12.
Vererbung:
Dieses Flag wird vererbt, sofern das Feld
tp_dictoffsetnicht in einer Oberklasse gesetzt ist.
-
Py_TPFLAGS_MANAGED_WEAKREF¶
Dieses Bit zeigt an, dass Instanzen der Klasse schwach referenzierbar sein sollen.
Ist dieses Flag gesetzt, muss auch
Py_TPFLAGS_HAVE_GCgesetzt sein.Added in version 3.12.
Vererbung:
Dieses Flag wird vererbt, sofern das Feld
tp_weaklistoffsetnicht in einer Oberklasse gesetzt ist.
-
Py_TPFLAGS_PREHEADER¶
Diese Bits zeigen an, dass die VM einige Felder verwaltet, indem sie sie vor dem Objekt ablegt. Derzeit entspricht dieses Makro Py_TPFLAGS_MANAGED_DICT | Py_TPFLAGS_MANAGED_WEAKREF.
Der Wert dieses Makros hängt von der Umsetzung der VM ab, er ist deshalb nicht stabil und kann sich in einer künftigen Version ändern. Verwende besser die einzelnen Flags.
Added in version 3.12.
-
Py_TPFLAGS_ITEMS_AT_END¶
- Teil der Stable ABI seit Version 3.12.
Nur bei Typen veränderlicher Größe verwendbar, also solchen mit einem
tp_itemsizeungleich null.Zeigt an, dass der Teil veränderlicher Größe einer Instanz dieses Typs am Ende des Speicherbereichs der Instanz liegt, beim Versatz
Py_TYPE(obj)->tp_basicsize(der in jeder Unterklasse anders sein kann).Vergewissere dich beim Setzen dieses Flags, dass alle Oberklassen entweder denselben Speicheraufbau verwenden oder nicht von veränderlicher Größe sind. Python prüft das nicht.
Added 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¶
Funktionen wie
PyLong_Check()rufenPyType_FastSubclass()mit einem dieser Flags auf, um schnell festzustellen, ob ein Typ eine Unterklasse eines integrierten Typs ist. Solche gezielten Prüfungen sind schneller als eine allgemeine Prüfung wiePyObject_IsInstance(). Bei eigenen Typen, die von integrierten Typen erben, solltetp_flagspassend gesetzt sein, sonst verhält sich der Code, der mit solchen Typen umgeht, je nach verwendeter Prüfung unterschiedlich.
-
Py_TPFLAGS_HAVE_FINALIZE¶
Dieses Bit ist gesetzt, wenn der Slot
tp_finalizein der Typstruktur vorhanden ist.Added in version 3.4.
Veraltet ab Version 3.8: Dieses Flag ist nicht mehr nötig, weil der Interpreter davon ausgeht, dass der Slot
tp_finalizein der Typstruktur immer vorhanden ist.
-
Py_TPFLAGS_HAVE_VECTORCALL¶
- Teil der Stable ABI seit Version 3.12.
Dieses Bit ist gesetzt, wenn die Klasse das vectorcall-Protokoll umsetzt. Einzelheiten stehen unter
tp_vectorcall_offset.Vererbung:
Dieses Bit wird vererbt, wenn auch
tp_callvererbt wird.Added in version 3.8: als
_Py_TPFLAGS_HAVE_VECTORCALLGeändert in Version 3.9: Auf den jetzigen Namen umbenannt, ohne den führenden Unterstrich. Der alte vorläufige Name ist sanft abgekündigt.
Geändert in Version 3.12: Dieses Flag wird jetzt von einer Klasse entfernt, wenn die Methode
__call__()der Klasse neu zugewiesen wird.Dieses Flag kann jetzt von veränderlichen Klassen geerbt werden.
-
Py_TPFLAGS_IMMUTABLETYPE¶
Dieses Bit ist bei Typobjekten gesetzt, die unveränderlich sind: Typattribute lassen sich weder setzen noch löschen.
PyType_Ready()setzt dieses Flag bei statischen Typen automatisch.Vererbung:
Dieses Flag wird nicht vererbt.
Added in version 3.10.
-
Py_TPFLAGS_DISALLOW_INSTANTIATION¶
Verbietet das Erzeugen von Instanzen des Typs: Es setzt
tp_newauf NULL und legt den Schlüssel__new__im Dictionary des Typs nicht an.Das Flag muss gesetzt werden, bevor der Typ erzeugt wird, nicht danach. Es muss zum Beispiel gesetzt sein, bevor
PyType_Ready()auf dem Typ aufgerufen wird.Bei statischen Typen wird das Flag automatisch gesetzt, wenn
tp_baseNULL oder&PyBaseObject_Typeist undtp_newNULL ist.Vererbung:
Dieses Flag wird nicht vererbt. Unterklassen lassen sich allerdings nur dann instanziieren, wenn sie ein
tp_newungleich NULL bereitstellen (was nur über die C-API möglich ist).Bemerkung
Um das unmittelbare Instanziieren einer Klasse zu verbieten, das Instanziieren ihrer Unterklassen aber zu erlauben (etwa bei einer abstrakten Basisklasse), verwende dieses Flag nicht. Lass stattdessen
tp_newnur bei Unterklassen gelingen.Added in version 3.10.
-
Py_TPFLAGS_MAPPING¶
Dieses Bit zeigt an, dass Instanzen der Klasse auf Mapping-Muster passen können, wenn sie als Gegenstand eines
match-Blocks verwendet werden. Es wird beim Registrieren oder Ableiten voncollections.abc.Mappingautomatisch gesetzt und beim Registrieren voncollections.abc.Sequencegelöscht.Bemerkung
Py_TPFLAGS_MAPPINGundPy_TPFLAGS_SEQUENCEschließen einander aus. Beide Flags gleichzeitig einzuschalten ist ein Fehler.Vererbung:
Dieses Flag wird an Typen vererbt, die nicht bereits
Py_TPFLAGS_SEQUENCEsetzen.Siehe auch
PEP 634 – Structural Pattern Matching: Specification
Added in version 3.10.
-
Py_TPFLAGS_SEQUENCE¶
Dieses Bit zeigt an, dass Instanzen der Klasse auf Sequenzmuster passen können, wenn sie als Gegenstand eines
match-Blocks verwendet werden. Es wird beim Registrieren oder Ableiten voncollections.abc.Sequenceautomatisch gesetzt und beim Registrieren voncollections.abc.Mappinggelöscht.Bemerkung
Py_TPFLAGS_MAPPINGundPy_TPFLAGS_SEQUENCEschließen einander aus. Beide Flags gleichzeitig einzuschalten ist ein Fehler.Vererbung:
Dieses Flag wird an Typen vererbt, die nicht bereits
Py_TPFLAGS_MAPPINGsetzen.Siehe auch
PEP 634 – Structural Pattern Matching: Specification
Added in version 3.10.
-
Py_TPFLAGS_VALID_VERSION_TAG¶
Intern. Setze oder lösche dieses Flag nicht. Um anzuzeigen, dass eine Klasse sich geändert hat, rufe
PyType_Modified()auf.Warnung
Dieses Flag ist in Header-Dateien vorhanden, wird aber nicht verwendet. Es wird in einer künftigen Version von CPython entfernt.
-
Py_TPFLAGS_HAVE_VERSION_TAG¶
Dieses Makro tut nichts. Früher zeigte es an, dass das Feld
tp_version_tagverfügbar und initialisiert war.Sanft abgekündigt <Soft deprecated> seit Version 3.13.
-
Py_TPFLAGS_INLINE_VALUES¶
Dieses Bit zeigt an, dass Instanzen dieses Typs ein Array mit „Inline-Werten“ haben (das die Attribute des Objekts enthält), das unmittelbar hinter dem Ende des Objekts liegt.
Das setzt voraus, dass
Py_TPFLAGS_HAVE_GCgesetzt ist.Vererbung:
Dieses Flag wird nicht vererbt.
Added in version 3.13.
-
Py_TPFLAGS_IS_ABSTRACT¶
Dieses Bit zeigt an, dass dies ein abstrakter Typ ist und sich deshalb nicht instanziieren lässt.
Vererbung:
Dieses Flag wird nicht vererbt.
Siehe auch
-
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION¶
Intern. Setze oder lösche dieses Flag nicht. Früher war das ein reserviertes Flag zur Verwendung in Stackless Python.
Warnung
Dieses Flag ist in Header-Dateien vorhanden, wird aber nicht verwendet. Es wird möglicherweise in einer künftigen Version von CPython entfernt.
-
Py_TPFLAGS_HEAPTYPE¶
-
const char *PyTypeObject.tp_doc¶
The corresponding slot ID
Py_tp_docis part of the Stable ABI.Ein wahlfreier Zeiger auf eine NUL-terminierte C-Zeichenkette mit dem Docstring für dieses Typobjekt. Er wird als Attribut
__doc__am Typ und an den Instanzen des Typs nach außen gegeben.Vererbung:
Dieses Feld wird nicht an Untertypen vererbt.
-
traverseproc PyTypeObject.tp_traverse¶
The corresponding slot ID
Py_tp_traverseis part of the Stable ABI.Ein wahlfreier Zeiger auf eine traverse-Funktion für die Speicherbereinigung. Sie wird nur verwendet, wenn das Flag-Bit
Py_TPFLAGS_HAVE_GCgesetzt ist.Die Dokumentation dazu steht unter Traversal.
Vererbung:
Gruppe:
Py_TPFLAGS_HAVE_GC,tp_traverse,tp_clearDieses Feld wird von Untertypen gemeinsam mit
tp_clearund dem Flag-BitPy_TPFLAGS_HAVE_GCvererbt: Das Flag-Bit,tp_traverseundtp_clearwerden alle vom Basistyp geerbt, wenn sie im Untertyp alle null sind.
-
inquiry PyTypeObject.tp_clear¶
The corresponding slot ID
Py_tp_clearis part of the Stable ABI.Ein wahlfreier Zeiger auf eine clear-Funktion. Die Signatur lautet:
int tp_clear(PyObject *);
Der Zweck dieser Funktion ist es, Referenzzyklen aufzubrechen, die ein zyklisches Isolat verursachen, damit die Objekte gefahrlos zerstört werden können. Ein geleertes Objekt ist ein teilweise zerstörtes Objekt. Es ist nicht verpflichtet, die Entwurfsinvarianten einzuhalten, die im gewöhnlichen Betrieb gelten.
tp_clearmuss keine Referenzen auf Objekte löschen, die nicht an Referenzzyklen teilnehmen können, etwa Python-Zeichenketten oder ganze Zahlen. Es kann aber bequem sein, alle Referenzen zu leeren und die Funktiontp_deallocdes Typs so zu schreiben, dass sietp_clearaufruft, um doppelten Code zu vermeiden. (Sei dir bewusst, dasstp_clearbereits aufgerufen worden sein kann. Rufe besser idempotente Funktionen wiePy_CLEAR()auf.)Jedes nicht triviale Aufräumen sollte in
tp_finalizeerfolgen statt intp_clear.Bemerkung
Gelingt es
tp_clearnicht, einen Referenzzyklus aufzubrechen, bleiben die Objekte im zyklischen Isolat möglicherweise auf Dauer nicht einsammelbar („Leck“). Siehegc.garbage.Bemerkung
Referenzierte Objekte (unmittelbar und mittelbar) können bereits geleert worden sein. Dass sie in einem widerspruchsfreien Zustand sind, ist nicht zugesichert.
Bemerkung
Die Funktion
tp_cleardarf aus jedem Thread aufgerufen werden.Bemerkung
Dass ein Objekt automatisch geleert wird, bevor sein Destruktor (
tp_dealloc) aufgerufen wird, ist nicht zugesichert.Diese Funktion unterscheidet sich vom Destruktor (
tp_dealloc) in folgender Hinsicht:Der Zweck des Leerens eines Objekts ist es, Referenzen auf andere Objekte zu entfernen, die an einem Referenzzyklus teilnehmen könnten. Der Zweck des Destruktors ist dagegen umfassender: Er muss alle Ressourcen freigeben, die ihm gehören, auch Referenzen auf Objekte, die an keinem Referenzzyklus teilnehmen können (etwa ganze Zahlen), sowie den Speicher des Objekts selbst (durch Aufruf von
tp_free).Wenn
tp_clearaufgerufen wird, halten andere Objekte möglicherweise noch Referenzen auf das zu leerende Objekt. Deshalb darftp_clearden Speicher des Objekts selbst nicht freigeben (tp_free). Der Destruktor wird dagegen erst aufgerufen, wenn keine (starken) Referenzen mehr bestehen, und muss das Objekt deshalb gefahrlos zerstören, indem er es freigibt.tp_clearwird möglicherweise nie automatisch aufgerufen. Der Destruktor eines Objekts wird dagegen einige Zeit, nachdem das Objekt unerreichbar geworden ist, automatisch aufgerufen (also wenn entweder keine Referenzen mehr auf das Objekt bestehen oder das Objekt Teil eines zyklischen Isolats ist).
Darüber, wann, ob und wie oft Python ein Objekt automatisch leert, werden keine Zusagen gemacht, außer:
Python leert ein Objekt nicht automatisch, wenn es erreichbar ist, also wenn eine Referenz darauf besteht und es nicht Teil eines zyklischen Isolats ist.
Python leert ein Objekt nicht automatisch, wenn es nicht automatisch finalisiert wurde (siehe
tp_finalize). (Hat der Finalisierer das Objekt wieder auferstehen lassen, kann es sein, dass das Objekt vor dem Leeren noch einmal automatisch finalisiert wird oder auch nicht.)Ist ein Objekt Teil eines zyklischen Isolats, leert Python es nicht automatisch, solange noch ein Mitglied des Isolats nicht automatisch finalisiert wurde (
tp_finalize).Python zerstört ein Objekt erst, nachdem alle automatischen Aufrufe seiner Funktion
tp_clearzurückgekehrt sind. Damit ist sichergestellt, dass das Aufbrechen eines Referenzzyklus den Zeigerselfnicht ungültig macht, währendtp_clearnoch läuft.Python ruft
tp_clearnicht automatisch mehrfach gleichzeitig auf.
CPython leert derzeit nur die Objekte automatisch, die nötig sind, um Referenzzyklen in einem zyklischen Isolat aufzubrechen. Künftige Versionen könnten Objekte aber regelmäßig vor ihrer Zerstörung leeren.
Zusammengenommen müssen alle Funktionen
tp_clearim System gemeinsam alle Referenzzyklen aufbrechen. Das ist feinsinnig, und im Zweifel stellst du besser eine Funktiontp_clearbereit. Der Typ tuple zum Beispiel setzt keine Funktiontp_clearum, weil sich beweisen lässt, dass kein Referenzzyklus ausschließlich aus Tupeln bestehen kann. Deshalb sind die Funktionentp_clearanderer Typen dafür zuständig, jeden Zyklus aufzubrechen, der ein Tupel enthält. Das ist nicht sofort offensichtlich, und es gibt selten einen guten Grund,tp_clearnicht umzusetzen.Umsetzungen von
tp_clearsollten die Referenzen der Instanz auf diejenigen ihrer Member fallen lassen, die Python-Objekte sein können, und ihre Zeiger auf diese Member aufNULLsetzen, wie im folgenden Beispiel:static 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, weil das Leeren von Referenzen heikel ist: Die Referenz auf das enthaltene Objekt darf erst dann freigegeben werden (überPy_DECREF()), nachdem der Zeiger auf das enthaltene Objekt aufNULLgesetzt wurde. Denn das Freigeben der Referenz kann dazu führen, dass das enthaltene Objekt zu Müll wird, was eine Kette von Aufräumvorgängen anstößt, die auch das Ausführen beliebigen Python-Codes umfassen kann (durch Finalisierer oder Weakref-Callbacks des enthaltenen Objekts). Kann solcher Code self erneut referenzieren, 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 Schritte in einer sicheren Reihenfolge aus.Ist das Bit
Py_TPFLAGS_MANAGED_DICTim Feldtp_flagsgesetzt, muss die clear-FunktionPyObject_ClearManagedDict()so aufrufen:PyObject_ClearManagedDict((PyObject*)self);
Mehr Informationen zum Verfahren der Speicherbereinigung in Python stehen im Abschnitt Supporting Cyclic Garbage Collection.
Vererbung:
Gruppe:
Py_TPFLAGS_HAVE_GC,tp_traverse,tp_clearDieses Feld wird von Untertypen gemeinsam mit
tp_traverseund dem Flag-BitPy_TPFLAGS_HAVE_GCvererbt: Das Flag-Bit,tp_traverseundtp_clearwerden alle vom Basistyp geerbt, wenn sie im Untertyp alle null sind.Siehe auch
Object Life Cycle – Einzelheiten dazu, wie dieser Slot mit den anderen Slots zusammenhängt.
-
richcmpfunc PyTypeObject.tp_richcompare¶
The corresponding slot ID
Py_tp_richcompareis part of the Stable ABI.Ein wahlfreier Zeiger auf die Funktion für den erweiterten Vergleich, deren Signatur lautet:
PyObject *tp_richcompare(PyObject *self, PyObject *other, int op);
Der erste Parameter ist garantiert eine Instanz des Typs, der durch
PyTypeObjectfestgelegt ist.Die Funktion sollte das Ergebnis des Vergleichs zurückgeben (üblicherweise
Py_TrueoderPy_False). Ist der Vergleich undefiniert, muss siePy_NotImplementedzurückgeben. Trat ein anderer Fehler auf, muss sieNULLzurückgeben und einen Ausnahmezustand setzen.Die folgenden Konstanten sind festgelegt, um als drittes Argument für
tp_richcompareund fürPyObject_RichCompare()verwendet zu werden:Konstante
Vergleich
-
Py_LT¶
<-
Py_LE¶
<=-
Py_EQ¶
==-
Py_NE¶
!=-
Py_GT¶
>-
Py_GE¶
>=Das folgende Makro ist festgelegt, um das Schreiben von Funktionen für den erweiterten Vergleich zu erleichtern:
-
Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, op)¶
Gibt je nach Ergebnis eines Vergleichs
Py_TrueoderPy_Falseaus der Funktion zurück. VAL_A und VAL_B müssen sich über die C-Vergleichsoperatoren ordnen lassen (sie dürfen zum Beispiel C-ints oder -floats sein). Das dritte Argument gibt den gewünschten Vorgang an, wie beiPyObject_RichCompare().Der zurückgegebene Wert ist eine neue starke Referenz.
Im Fehlerfall setzt es eine Ausnahme und gibt
NULLaus der Funktion zurück.Added in version 3.7.
Vererbung:
Gruppe:
tp_hash,tp_richcompareDieses Feld wird von Untertypen gemeinsam mit
tp_hashvererbt: Ein Untertyp erbttp_richcompareundtp_hash, wenntp_richcompareundtp_hashdes Untertyps beideNULLsind.Vorgabe:
PyBaseObject_Typestellt eine Umsetzung vontp_richcomparebereit, die geerbt werden kann. Ist allerdings nurtp_hashfestgelegt, wird nicht einmal die geerbte Funktion verwendet, und Instanzen des Typs können an keinerlei Vergleichen teilnehmen.-
Py_LT¶
-
Py_ssize_t PyTypeObject.tp_weaklistoffset¶
Dieses Feld wird zwar weiterhin unterstützt, aber nach Möglichkeit sollte stattdessen
Py_TPFLAGS_MANAGED_WEAKREFverwendet werden.Sind die Instanzen dieses Typs schwach referenzierbar, ist dieses Feld größer als null und enthält den Versatz des Kopfes der Liste schwacher Referenzen in der Instanzstruktur (ohne den GC-Kopf, falls vorhanden). Dieser Versatz wird von
PyObject_ClearWeakRefs()und denPyWeakref_*-Funktionen verwendet. Die Instanzstruktur muss ein Feld vom Typ PyObject* enthalten, das aufNULLinitialisiert wird.Verwechsle dieses Feld nicht mit
tp_weaklist. Das ist der Listenkopf 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 an Untertypen vererbt, siehe aber die unten aufgeführten Regeln. Ein Untertyp darf diesen Versatz übergehen. Das bedeutet, dass der Untertyp einen anderen Kopf der Liste schwacher Referenzen verwendet als der Basistyp. Da der Listenkopf immer über
tp_weaklistoffsetgefunden wird, sollte das kein Problem sein.Vorgabe:
Ist das Bit
Py_TPFLAGS_MANAGED_WEAKREFim Feldtp_flagsgesetzt, wirdtp_weaklistoffsetauf einen negativen Wert gesetzt, um anzuzeigen, dass es nicht gefahrlos verwendet werden kann.
-
getiterfunc PyTypeObject.tp_iter¶
The corresponding slot ID
Py_tp_iteris part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion, die einen Iterator für das Objekt zurückgibt. Sein Vorhandensein zeigt normalerweise an, dass die Instanzen dieses Typs iterierbar sind (Sequenzen können allerdings auch ohne diese Funktion iterierbar sein).
Diese Funktion hat dieselbe Signatur wie
PyObject_GetIter():PyObject *tp_iter(PyObject *self);
Vererbung:
Dieses Feld wird an Untertypen vererbt.
-
iternextfunc PyTypeObject.tp_iternext¶
The corresponding slot ID
Py_tp_iternextis part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion, die das nächste Element eines Iterators zurückgibt. Die Signatur lautet:
PyObject *tp_iternext(PyObject *self);
Ist der Iterator erschöpft, muss die Funktion
tp_iternextNULLzurückgeben. EineStopIteration-Ausnahme kann gesetzt sein oder auch nicht. Tritt ein anderer Fehler auf, muss sie ebenfallsNULLzurückgeben. Das Vorhandensein vontp_iternextzeigt an, dass die Instanzen dieses Typs Iteratoren sind.Iteratortypen sollten außerdem die Funktion
tp_iterfestlegen, und diese Funktion sollte die Iterator-Instanz selbst zurückgeben (keine neue Iterator-Instanz).Diese Funktion hat dieselbe Signatur wie
PyIter_Next().Vererbung:
Dieses Feld wird an Untertypen vererbt.
-
struct PyMethodDef *PyTypeObject.tp_methods¶
The corresponding slot ID
Py_tp_methodsis part of the Stable ABI.Ein wahlfreier Zeiger auf ein statisches,
NULL-terminiertes Array vonPyMethodDef-Strukturen, die die gewöhnlichen Methoden dieses Typs deklarieren.Für jeden Eintrag im Array wird dem Dictionary des Typs (siehe
tp_dictunten) ein Eintrag mit einem Methodendeskriptor hinzugefügt.Vererbung:
Dieses Feld wird nicht an Untertypen vererbt (Methoden werden über einen anderen Mechanismus vererbt).
-
struct PyMemberDef *PyTypeObject.tp_members¶
The corresponding slot ID
Py_tp_membersis part of the Stable ABI.Ein wahlfreier Zeiger auf ein statisches,
NULL-terminiertes Array vonPyMemberDef-Strukturen, die die gewöhnlichen Datenmember (Felder oder Slots) von Instanzen dieses Typs deklarieren.Für jeden Eintrag im Array wird dem Dictionary des Typs (siehe
tp_dictunten) ein Eintrag mit einem Member-Deskriptor hinzugefügt.Vererbung:
Dieses Feld wird nicht an Untertypen vererbt (Member werden über einen anderen Mechanismus vererbt).
-
struct PyGetSetDef *PyTypeObject.tp_getset¶
The corresponding slot ID
Py_tp_getsetis part of the Stable ABI.Ein wahlfreier Zeiger auf ein statisches,
NULL-terminiertes Array vonPyGetSetDef-Strukturen, die berechnete Attribute von Instanzen dieses Typs deklarieren.Für jeden Eintrag im Array wird dem Dictionary des Typs (siehe
tp_dictunten) ein Eintrag mit einem getset-Deskriptor hinzugefügt.Vererbung:
Dieses Feld wird nicht an Untertypen vererbt (berechnete Attribute werden über einen anderen Mechanismus vererbt).
-
PyTypeObject *PyTypeObject.tp_base¶
Ein wahlfreier Zeiger auf einen Basistyp, von dem Typeigenschaften geerbt werden. Auf dieser Ebene wird nur Einfachvererbung unterstützt; Mehrfachvererbung erfordert, ein Typobjekt dynamisch durch Aufruf des Metatyps zu erzeugen.
Die zugehörige Slot-ID steht unter
Py_tp_base.Bemerkung
Für das Initialisieren von Slots gelten die Regeln zum Initialisieren von Globalen. C99 verlangt, dass die Initialisierer „Adresskonstanten“ sind. Funktionsbezeichner wie
PyType_GenericNew()sind mit ihrer stillschweigenden Umwandlung in einen Zeiger gültige C99-Adresskonstanten.Der unäre Operator „&“, angewendet auf eine nicht statische Variable wie
PyBaseObject_Type, muss dagegen keine Adresskonstante ergeben. Compiler dürfen das unterstützen (gcc tut es), MSVC tut es nicht. Beide Compiler halten sich in diesem Punkt streng an den Standard.Folglich sollte
tp_basein der init-Funktion des Erweiterungsmoduls gesetzt werden.Vererbung:
Dieses Feld wird (selbstverständlich) nicht an Untertypen vererbt.
Vorgabe:
Dieses Feld ist auf
&PyBaseObject_Typevoreingestellt (was Python-Programmierer als den Typobjectkennen).
-
PyObject *PyTypeObject.tp_dict¶
Das Dictionary des Typs wird hier von
PyType_Ready()abgelegt.Dieses Feld sollte normalerweise auf
NULLinitialisiert werden, bevor PyType_Ready aufgerufen wird. Es darf auch mit einem Dictionary mit Anfangsattributen für den Typ initialisiert werden. SobaldPyType_Ready()den Typ initialisiert hat, dürfen diesem Dictionary nur dann weitere Attribute für den Typ hinzugefügt werden, wenn sie nicht zu überladenen Operationen gehören (wie__add__()). Ist die Initialisierung des Typs abgeschlossen, sollte dieses Feld als nur lesbar behandelt werden.Manche Typen legen ihr Dictionary nicht in diesem Slot ab. Verwende
PyType_GetDict(), um das Dictionary eines beliebigen Typs zu holen.Geändert in Version 3.12: Zu den Interna: Bei statischen integrierten Typen ist das immer
NULL. Das Dictionary solcher Typen liegt stattdessen amPyInterpreterState. VerwendePyType_GetDict(), um das Dictionary eines beliebigen Typs zu bekommen.Vererbung:
Dieses Feld wird nicht an Untertypen vererbt (die hier festgelegten Attribute werden allerdings über einen anderen Mechanismus vererbt).
Vorgabe:
Ist dieses Feld
NULL, weistPyType_Ready()ihm ein neues Dictionary zu.Warnung
Es ist nicht gefahrlos möglich,
PyDict_SetItem()auftp_dictanzuwenden oder es anderweitig über die Dictionary-C-API zu ändern.
-
descrgetfunc PyTypeObject.tp_descr_get¶
The corresponding slot ID
Py_tp_descr_getis part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion zum Lesen eines Deskriptors („descriptor get“).
Die Signatur der Funktion lautet:
PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);
Vererbung:
Dieses Feld wird an Untertypen vererbt.
-
descrsetfunc PyTypeObject.tp_descr_set¶
The corresponding slot ID
Py_tp_descr_setis part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion zum Setzen und Löschen des Werts eines Deskriptors.
Die Signatur der Funktion lautet:
int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);
Das Argument value wird auf
NULLgesetzt, um den Wert zu löschen.Vererbung:
Dieses Feld wird an Untertypen vererbt.
-
Py_ssize_t PyTypeObject.tp_dictoffset¶
Dieses Feld wird zwar weiterhin unterstützt, aber nach Möglichkeit sollte stattdessen
Py_TPFLAGS_MANAGED_DICTverwendet werden.Haben die Instanzen dieses Typs ein Dictionary mit Instanzvariablen, ist dieses Feld ungleich null und enthält den Versatz des Dictionarys der Instanzvariablen in den Instanzen des Typs. Dieser Versatz wird von
PyObject_GenericGetAttr()verwendet.Verwechsle dieses Feld nicht mit
tp_dict. Das ist das Dictionary für die Attribute des Typobjekts selbst.Der Wert gibt den Versatz des Dictionarys vom Anfang der Instanzstruktur an.
tp_dictoffsetsollte als nur schreibbar betrachtet werden. Um den Zeiger auf das Dictionary zu bekommen, rufePyObject_GenericGetDict()auf. Der Aufruf vonPyObject_GenericGetDict()muss möglicherweise Speicher für das Dictionary anfordern, deshalb kann es wirksamer sein,PyObject_GetAttr()aufzurufen, wenn du auf ein Attribut des Objekts zugreifst.Es ist ein Fehler, sowohl das Bit
Py_TPFLAGS_MANAGED_DICTals auchtp_dictoffsetzu setzen.Vererbung:
Dieses Feld wird an Untertypen vererbt. Ein Untertyp sollte diesen Versatz nicht übergehen. Das könnte gefährlich sein, wenn C-Code versucht, auf das Dictionary beim bisherigen Versatz zuzugreifen. Um Vererbung richtig zu unterstützen, verwende
Py_TPFLAGS_MANAGED_DICT.Vorgabe:
Dieser Slot hat keine Vorgabe. Bei statischen Typen wird für Instanzen kein
__dict__angelegt, wenn das FeldNULList.Ist das Bit
Py_TPFLAGS_MANAGED_DICTim Feldtp_flagsgesetzt, wirdtp_dictoffsetauf-1gesetzt, um anzuzeigen, dass es nicht gefahrlos verwendet werden kann.
-
initproc PyTypeObject.tp_init¶
The corresponding slot ID
Py_tp_initis part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion zur Initialisierung von Instanzen.
Diese Funktion entspricht der Methode
__init__()von Klassen. Wie bei__init__()lässt sich eine Instanz erzeugen, ohne__init__()aufzurufen, und eine Instanz lässt sich neu initialisieren, indem ihre Methode__init__()erneut aufgerufen wird.Die Signatur der Funktion lautet:
int tp_init(PyObject *self, PyObject *args, PyObject *kwds);
Das Argument self ist die zu initialisierende Instanz. Die Argumente args und kwds stehen für die Positions- und Schlüsselwortargumente des Aufrufs von
__init__().Die Funktion
tp_initwird, sofern sie nichtNULList, aufgerufen, wenn eine Instanz auf gewöhnlichem Weg durch Aufruf ihres Typs erzeugt wird, nachdem die Funktiontp_newdes Typs eine Instanz des Typs zurückgegeben hat. Gibt die Funktiontp_neweine Instanz eines anderen Typs zurück, der kein Untertyp des ursprünglichen Typs ist, wird keine Funktiontp_initaufgerufen. Gibttp_neweine Instanz eines Untertyps des ursprünglichen Typs zurück, wirdtp_initdes Untertyps aufgerufen.Gibt bei Erfolg
0zurück, im Fehlerfall-1, und setzt eine Ausnahme.Vererbung:
Dieses Feld wird an Untertypen vererbt.
Vorgabe:
Bei statischen Typen hat dieses Feld keine Vorgabe.
-
allocfunc PyTypeObject.tp_alloc¶
The corresponding slot ID
Py_tp_allocis part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion zur Speicheranforderung für Instanzen.
Die Signatur der Funktion lautet:
PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems);
Vererbung:
Statische Untertypen erben diesen Slot. Er ist
PyType_GenericAlloc(), wenn er vonobjectgeerbt wird.Heap-Untertypen erben diesen Slot nicht.
Vorgabe:
Bei Heap-Untertypen ist dieses Feld immer auf
PyType_GenericAlloc()gesetzt.Bei statischen Untertypen wird dieser Slot vererbt (siehe oben).
-
newfunc PyTypeObject.tp_new¶
The corresponding slot ID
Py_tp_newis part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion zum Erzeugen von Instanzen.
Die Signatur der Funktion lautet:
PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds);
Das Argument subtype ist der Typ des zu erzeugenden Objekts. Die Argumente args und kwds stehen für die Positions- und Schlüsselwortargumente des Aufrufs des Typs. Beachte, dass subtype nicht gleich dem Typ sein muss, dessen Funktion
tp_newaufgerufen wird. Es darf ein Untertyp dieses Typs sein (aber kein unverwandter Typ).Die Funktion
tp_newsolltesubtype->tp_alloc(subtype, nitems)aufrufen, um Platz für das Objekt anzufordern, und danach nur so viel weitere Initialisierung vornehmen, wie unbedingt nötig ist. Initialisierung, die sich gefahrlos überspringen oder wiederholen lässt, gehört in den Handlertp_init. Als Faustregel gilt: Bei unveränderlichen Typen sollte alle Initialisierung intp_newstattfinden, bei veränderlichen Typen sollte das meiste auftp_initverschoben werden.Setze das Flag
Py_TPFLAGS_DISALLOW_INSTANTIATION, um das Erzeugen von Instanzen des Typs in Python zu verbieten.Vererbung:
Dieses Feld wird an Untertypen vererbt, außer an statische Typen, deren
tp_baseNULLoder&PyBaseObject_Typeist.Vorgabe:
Bei statischen Typen hat dieses Feld keine Vorgabe. Das bedeutet: Ist der Slot als
NULLfestgelegt, lässt sich der Typ nicht aufrufen, um neue Instanzen zu erzeugen. Vermutlich gibt es dann einen anderen Weg, Instanzen zu erzeugen, etwa eine Factory-Funktion.
-
freefunc PyTypeObject.tp_free¶
The corresponding slot ID
Py_tp_freeis part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion zur Speicherfreigabe für Instanzen. Ihre Signatur lautet:
void tp_free(void *self);
Diese Funktion muss den Speicher freigeben, den
tp_allocangefordert hat.Vererbung:
Statische Untertypen erben diesen Slot. Er ist
PyObject_Free(), wenn er vonobjectgeerbt wird. Ausnahme: Unterstützt der Typ die Speicherbereinigung (ist also das FlagPy_TPFLAGS_HAVE_GCintp_flagsgesetzt) und würde erPyObject_Free()erben, wird dieser Slot nicht vererbt, sondern ist aufPyObject_GC_Del()voreingestellt.Heap-Untertypen erben diesen Slot nicht.
Vorgabe:
Bei Heap-Untertypen ist dieser Slot auf einen Deallokator voreingestellt, der zu
PyType_GenericAlloc()und zum Wert des FlagsPy_TPFLAGS_HAVE_GCpasst.Bei statischen Untertypen wird dieser Slot vererbt (siehe oben).
-
inquiry PyTypeObject.tp_is_gc¶
The corresponding slot ID
Py_tp_is_gcis part of the Stable ABI.Ein wahlfreier Zeiger auf eine Funktion, die die Speicherbereinigung aufruft.
Die Speicherbereinigung muss wissen, ob ein bestimmtes Objekt einsammelbar ist oder nicht. Normalerweise genügt es, das Feld
tp_flagsdes Typs des Objekts anzusehen und das Flag-BitPy_TPFLAGS_HAVE_GCzu prüfen. Manche Typen haben aber eine Mischung aus statisch und dynamisch angelegten Instanzen, und die statisch angelegten Instanzen sind nicht einsammelbar. Solche Typen sollten diese Funktion festlegen. Sie sollte1für eine einsammelbare und0für eine nicht einsammelbare Instanz zurückgeben. Die Signatur lautet:int tp_is_gc(PyObject *self);
(Das einzige Beispiel dafür sind die Typen selbst. Der Metatyp
PyType_Typelegt diese Funktion fest, um zwischen statisch und dynamisch angelegten Typen zu unterscheiden.)Vererbung:
Dieses Feld wird an Untertypen vererbt.
Vorgabe:
Dieser Slot hat keine Vorgabe. Ist dieses Feld
NULL, wirdPy_TPFLAGS_HAVE_GCals funktionale Entsprechung verwendet.
-
PyObject *PyTypeObject.tp_bases¶
Tupel der Basistypen.
Dieses Feld sollte auf
NULLgesetzt und als nur lesbar behandelt werden. Python füllt es, wenn der Typinitialisiertwird.Die zugehörige Slot-ID steht unter
Py_tp_bases.Warnung
Mehrfachvererbung funktioniert bei statisch festgelegten Typen nicht gut. Setzt du
tp_basesauf ein Tupel, löst Python zwar keinen Fehler aus, manche Slots werden aber nur vom ersten Basistyp geerbt.Vererbung:
Dieses Feld wird nicht vererbt.
-
PyObject *PyTypeObject.tp_mro¶
Tupel mit der aufgefalteten Menge der Basistypen, beginnend mit dem Typ selbst und endend mit
object, in der Reihenfolge der Methodenauflösung.Dieses Feld sollte auf
NULLgesetzt und als nur lesbar behandelt werden. Python füllt es, wenn der Typinitialisiertwird.Vererbung:
Dieses Feld wird nicht vererbt. Es wird von
PyType_Ready()neu berechnet.
-
PyObject *PyTypeObject.tp_cache¶
Unbenutzt. Nur für den internen Gebrauch.
Vererbung:
Dieses Feld wird nicht vererbt.
-
void *PyTypeObject.tp_subclasses¶
Eine Sammlung von Unterklassen. Nur für den internen Gebrauch. Kann ein ungültiger Zeiger sein.
Um eine Liste der Unterklassen zu bekommen, rufe die Python-Methode
__subclasses__()auf.Geändert in Version 3.12: Bei manchen Typen enthält dieses Feld keinen gültigen PyObject*. Der Typ wurde zu void* geändert, um das anzuzeigen.
Vererbung:
Dieses Feld wird nicht vererbt.
-
PyObject *PyTypeObject.tp_weaklist¶
Kopf der Liste schwacher Referenzen, für schwache Referenzen auf dieses Typobjekt. Wird nicht vererbt. Nur für den internen Gebrauch.
Geändert in Version 3.12: Zu den Interna: Bei den statischen integrierten Typen ist das immer
NULL, auch wenn schwache Referenzen hinzugefügt werden. Die schwachen Referenzen jedes einzelnen liegen stattdessen amPyInterpreterState. Verwende die öffentliche C-API oder das interne Makro_PyObject_GET_WEAKREFS_LISTPTR(), um dir diese Unterscheidung zu ersparen.Vererbung:
Dieses Feld wird nicht vererbt.
-
destructor PyTypeObject.tp_del¶
The corresponding slot ID
Py_tp_delis part of the Stable ABI.Dieses Feld ist veraltet. Verwende stattdessen
tp_finalize.
-
unsigned int PyTypeObject.tp_version_tag¶
Dient als Index in den Methoden-Cache. Nur für den internen Gebrauch.
Vererbung:
Dieses Feld wird nicht vererbt.
-
destructor PyTypeObject.tp_finalize¶
The corresponding slot ID
Py_tp_finalizeis part of the Stable ABI seit Version 3.5.Ein wahlfreier Zeiger auf eine Funktion zur Finalisierung von Instanzen. Das ist die C-Umsetzung der speziellen Methode
__del__(). Ihre Signatur lautet:void tp_finalize(PyObject *self);
Der Hauptzweck der Finalisierung ist es, nicht triviale Aufräumarbeiten zu erledigen, die vor der Zerstörung des Objekts stattfinden müssen, solange das Objekt und alle Objekte, die es unmittelbar oder mittelbar referenziert, noch in einem widerspruchsfreien Zustand sind. Der Finalisierer darf beliebigen Python-Code ausführen.
Bevor Python ein Objekt automatisch finalisiert, können einige der unmittelbar oder mittelbar referenzierten Objekte ihrerseits bereits automatisch finalisiert worden sein. Keines der referenzierten Objekte wird zu diesem Zeitpunkt aber bereits automatisch geleert worden sein (
tp_clear).Andere, noch nicht finalisierte Objekte verwenden ein finalisiertes Objekt möglicherweise noch, deshalb muss der Finalisierer das Objekt in einem vernünftigen Zustand hinterlassen (die Invarianten müssen also weiterhin gelten).
Bemerkung
Nachdem Python ein Objekt automatisch finalisiert hat, beginnt es möglicherweise damit, das Objekt und die von ihm referenzierten Objekte (unmittelbar und mittelbar) automatisch zu leeren (
tp_clear). Dass geleerte Objekte in einem widerspruchsfreien Zustand sind, ist nicht zugesichert. Ein finalisiertes Objekt muss geleerte referenzierte Objekte verkraften.Bemerkung
Dass ein Objekt automatisch finalisiert wird, bevor sein Destruktor (
tp_dealloc) aufgerufen wird, ist nicht zugesichert. Es wird empfohlen, am Anfang vontp_deallocPyObject_CallFinalizerFromDealloc()aufzurufen, damit das Objekt vor der Zerstörung in jedem Fall finalisiert ist.Bemerkung
Die Funktion
tp_finalizedarf aus jedem Thread aufgerufen werden, der GIL wird dabei allerdings gehalten.Bemerkung
Die Funktion
tp_finalizekann beim Herunterfahren aufgerufen werden, nachdem einige globale Variablen bereits gelöscht wurden. Einzelheiten stehen in der Dokumentation zur Methode__del__().Wenn Python ein Objekt finalisiert, verhält es sich wie der folgende Algorithmus:
Python markiert das Objekt möglicherweise als finalisiert. Derzeit markiert Python immer Objekte, deren Typ die Speicherbereinigung unterstützt (bei denen also das Flag
Py_TPFLAGS_HAVE_GCintp_flagsgesetzt ist), und nie andere Arten von Objekten. Das kann sich in einer künftigen Version ändern.Ist das Objekt nicht als finalisiert markiert und ist seine Finalisiererfunktion
tp_finalizeungleichNULL, wird die Finalisiererfunktion aufgerufen.Wurde die Finalisiererfunktion aufgerufen und hat der Finalisierer das Objekt wieder erreichbar gemacht (besteht also eine Referenz darauf und ist es nicht Teil eines zyklischen Isolats), sagt man, der Finalisierer habe das Objekt wieder auferstehen lassen. Es ist nicht festgelegt, ob der Finalisierer das Objekt auch dadurch auferstehen lassen kann, dass er eine neue Referenz darauf hinzufügt, die es nicht erreichbar macht, das Objekt also (weiterhin) Teil eines zyklischen Isolats ist.
Hat der Finalisierer das Objekt wieder auferstehen lassen, wird die anstehende Zerstörung des Objekts abgebrochen, und die Markierung finalisiert wird möglicherweise entfernt, sofern vorhanden. Derzeit entfernt Python die Markierung finalisiert nie. Das kann sich in einer künftigen Version ändern.
Automatische Finalisierung bezeichnet jede Finalisierung, die Python vornimmt, außer über Aufrufe von
PyObject_CallFinalizer()oderPyObject_CallFinalizerFromDealloc(). Darüber, wann, ob und wie oft ein Objekt automatisch finalisiert wird, werden keine Zusagen gemacht, außer:Python finalisiert ein Objekt nicht automatisch, wenn es erreichbar ist, also wenn eine Referenz darauf besteht und es nicht Teil eines zyklischen Isolats ist.
Python finalisiert ein Objekt nicht automatisch, wenn das Finalisieren das Objekt nicht als finalisiert markieren würde. Derzeit trifft das auf Objekte zu, deren Typ die Speicherbereinigung nicht unterstützt, bei denen also das Flag
Py_TPFLAGS_HAVE_GCnicht gesetzt ist. Solche Objekte lassen sich weiterhin von Hand finalisieren, indemPyObject_CallFinalizer()oderPyObject_CallFinalizerFromDealloc()aufgerufen wird.Python finalisiert nie zwei Mitglieder eines zyklischen Isolats gleichzeitig automatisch.
Python finalisiert ein Objekt nicht automatisch, nachdem es das Objekt automatisch geleert hat (
tp_clear).Ist ein Objekt Teil eines zyklischen Isolats, finalisiert Python es nicht automatisch, nachdem es irgendein anderes Mitglied automatisch geleert hat (siehe
tp_clear).Python finalisiert jedes Mitglied eines zyklischen Isolats automatisch, bevor es irgendeines davon automatisch leert (siehe
tp_clear).Will Python ein Objekt automatisch leeren (
tp_clear), finalisiert es das Objekt vorher automatisch.
CPython finalisiert derzeit nur Objekte automatisch, die Teil eines zyklischen Isolats sind. Künftige Versionen könnten Objekte aber regelmäßig vor ihrer Zerstörung finalisieren.
Um ein Objekt von Hand zu finalisieren, rufe diese Funktion nicht unmittelbar auf. Rufe stattdessen
PyObject_CallFinalizer()oderPyObject_CallFinalizerFromDealloc()auf.tp_finalizesollte den aktuellen Ausnahmezustand unverändert lassen. Der empfohlene Weg, einen nicht trivialen Finalisierer zu schreiben, ist, die Ausnahme am Anfang mitPyErr_GetRaisedException()zu sichern und am Ende mitPyErr_SetRaisedException()wiederherzustellen. Stößt du mitten im Finalisierer auf eine Ausnahme, protokolliere und lösche sie mitPyErr_WriteUnraisable()oderPyErr_FormatUnraisable(). Zum Beispiel:static 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 an Untertypen vererbt.
Added in version 3.4.
Geändert in Version 3.8: Vor Version 3.8 musste das Flag-Bit
Py_TPFLAGS_HAVE_FINALIZEgesetzt sein, damit dieses Feld verwendet wurde. Das ist nicht mehr nötig.Siehe auch
PEP 442: „Safe object finalization“
Object Life Cycle – Einzelheiten dazu, wie dieser Slot mit den anderen Slots zusammenhängt.
-
vectorcallfunc PyTypeObject.tp_vectorcall¶
The corresponding slot ID
Py_tp_vectorcallis part of the Stable ABI seit Version 3.14.Eine vectorcall-Funktion, die für Aufrufe dieses Typobjekts (nicht seiner Instanzen) verwendet wird. Mit anderen Worten lässt sich über
tp_vectorcalltype.__call__optimieren, das üblicherweise 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.Bemerkung
Das vectorcall-Protokoll verlangt, dass die vectorcall-Funktion sich genauso verhält wie das zugehörige
tp_call. Das bedeutet, dasstype->tp_vectorcallzum Verhalten vonPy_TYPE(type)->tp_callpassen muss.Specifically, if type uses the default metaclass,
type->tp_vectorcallmust behave the same asPy_TYPE(type)->tp_call, which:type->tp_newaufruft,type->tp_initauf dem Ergebnis vontp_newaufruft, wenn das Ergebnis eine Unterklasse von type ist, unddas Ergebnis von
tp_newzurückgibt.
Üblicherweise wird
tp_vectorcallübergangen, um diesen Ablauf für bestimmtetp_newundtp_initzu optimieren. Tust du das bei Typen, von denen Nutzer Unterklassen bilden können, beachte, dass beide übergangen werden können (über__new__()beziehungsweise__init__()).Vererbung:
Dieses Feld wird nie vererbt.
Added in version 3.9: (das Feld gibt es seit 3.8, verwendet wird es aber erst seit 3.9)
-
unsigned char PyTypeObject.tp_watched¶
Intern. Nicht verwenden.
Added in version 3.12.
Statische Typen¶
Herkömmlich sind Typen, die in C-Code festgelegt werden, statisch, das heißt: Eine statische PyTypeObject-Struktur wird unmittelbar im Code festgelegt und über PyType_Ready() initialisiert.
Daraus ergeben sich Typen, die gegenüber in Python festgelegten Typen eingeschränkt sind:
Statische Typen sind auf einen Basistyp beschränkt, können also keine Mehrfachvererbung nutzen.
Statische Typobjekte (nicht unbedingt aber ihre Instanzen) sind unveränderlich. Die Attribute des Typobjekts lassen sich aus Python heraus weder hinzufügen noch ändern.
Statische Typobjekte werden von allen Unterinterpretern gemeinsam genutzt, sie sollten deshalb keinen Zustand enthalten, der einem einzelnen Unterinterpreter eigen ist.
Da PyTypeObject außerdem nur als undurchsichtige Struktur Teil der Limited API ist, müssen Erweiterungsmodule, die statische Typen verwenden, für eine bestimmte Python-Nebenversion kompiliert werden.
Heap-Typen¶
Eine Alternative zu statischen Typen sind auf dem Heap angelegte Typen, kurz Heap-Typen, die den Klassen, die Pythons class-Anweisung erzeugt, sehr nahekommen. Bei Heap-Typen ist das Flag Py_TPFLAGS_HEAPTYPE gesetzt.
Das geschieht, indem eine PyType_Spec-Struktur gefüllt und PyType_FromSpec(), PyType_FromSpecWithBases(), PyType_FromModuleAndSpec() oder PyType_FromMetaclass() aufgerufen wird.
Strukturen für Zahlenobjekte¶
-
type PyNumberMethods¶
Diese Struktur enthält Zeiger auf die Funktionen, über die ein Objekt das Zahlenprotokoll umsetzt. Jede Funktion wird von der gleichnamigen Funktion verwendet, die im Abschnitt Number Protocol dokumentiert ist.
Hier 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;
Bemerkung
Binäre und ternäre Funktionen müssen den Typ all ihrer Operanden prüfen und die nötigen Umwandlungen vornehmen (mindestens einer der Operanden ist eine Instanz des festgelegten Typs). Ist der Vorgang für die gegebenen Operanden nicht festgelegt, müssen binäre und ternäre Funktionen
Py_NotImplementedzurückgeben. Trat ein anderer Fehler auf, müssen sieNULLzurückgeben und eine Ausnahme setzen.Bemerkung
Das Feld
nb_reservedsollte immerNULLsein. Es hieß frühernb_longund wurde in Python 3.0.1 umbenannt.
-
binaryfunc PyNumberMethods.nb_add¶
The corresponding slot ID
Py_nb_addis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_subtract¶
The corresponding slot ID
Py_nb_subtractis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_multiply¶
The corresponding slot ID
Py_nb_multiplyis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_remainder¶
The corresponding slot ID
Py_nb_remainderis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_divmod¶
The corresponding slot ID
Py_nb_divmodis part of the Stable ABI.
-
ternaryfunc PyNumberMethods.nb_power¶
The corresponding slot ID
Py_nb_poweris part of the Stable ABI.
-
unaryfunc PyNumberMethods.nb_negative¶
The corresponding slot ID
Py_nb_negativeis part of the Stable ABI.
-
unaryfunc PyNumberMethods.nb_positive¶
The corresponding slot ID
Py_nb_positiveis part of the Stable ABI.
-
unaryfunc PyNumberMethods.nb_absolute¶
The corresponding slot ID
Py_nb_absoluteis part of the Stable ABI.
-
inquiry PyNumberMethods.nb_bool¶
The corresponding slot ID
Py_nb_boolis part of the Stable ABI.
-
unaryfunc PyNumberMethods.nb_invert¶
The corresponding slot ID
Py_nb_invertis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_lshift¶
The corresponding slot ID
Py_nb_lshiftis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_rshift¶
The corresponding slot ID
Py_nb_rshiftis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_and¶
The corresponding slot ID
Py_nb_andis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_xor¶
The corresponding slot ID
Py_nb_xoris part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_or¶
The corresponding slot ID
Py_nb_oris part of the Stable ABI.
-
unaryfunc PyNumberMethods.nb_int¶
The corresponding slot ID
Py_nb_intis part of the Stable ABI.
-
void *PyNumberMethods.nb_reserved¶
-
unaryfunc PyNumberMethods.nb_float¶
The corresponding slot ID
Py_nb_floatis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_inplace_add¶
The corresponding slot ID
Py_nb_inplace_addis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_inplace_subtract¶
The corresponding slot ID
Py_nb_inplace_subtractis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_inplace_multiply¶
The corresponding slot ID
Py_nb_inplace_multiplyis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_inplace_remainder¶
The corresponding slot ID
Py_nb_inplace_remainderis part of the Stable ABI.
-
ternaryfunc PyNumberMethods.nb_inplace_power¶
The corresponding slot ID
Py_nb_inplace_poweris part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_inplace_lshift¶
The corresponding slot ID
Py_nb_inplace_lshiftis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_inplace_rshift¶
The corresponding slot ID
Py_nb_inplace_rshiftis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_inplace_and¶
The corresponding slot ID
Py_nb_inplace_andis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_inplace_xor¶
The corresponding slot ID
Py_nb_inplace_xoris part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_inplace_or¶
The corresponding slot ID
Py_nb_inplace_oris part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_floor_divide¶
The corresponding slot ID
Py_nb_floor_divideis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_true_divide¶
The corresponding slot ID
Py_nb_true_divideis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_inplace_floor_divide¶
The corresponding slot ID
Py_nb_inplace_floor_divideis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_inplace_true_divide¶
The corresponding slot ID
Py_nb_inplace_true_divideis part of the Stable ABI.
-
unaryfunc PyNumberMethods.nb_index¶
The corresponding slot ID
Py_nb_indexis part of the Stable ABI.
-
binaryfunc PyNumberMethods.nb_matrix_multiply¶
The corresponding slot ID
Py_nb_matrix_multiplyis part of the Stable ABI seit Version 3.5.
-
binaryfunc PyNumberMethods.nb_inplace_matrix_multiply¶
The corresponding slot ID
Py_nb_inplace_matrix_multiplyis part of the Stable ABI seit Version 3.5.
Strukturen für Mapping-Objekte¶
-
type PyMappingMethods¶
Diese Struktur enthält Zeiger auf die Funktionen, über die ein Objekt das Mapping-Protokoll umsetzt. Sie hat drei Member:
-
lenfunc PyMappingMethods.mp_length¶
The corresponding slot ID
Py_mp_lengthis part of the Stable ABI.Diese Funktion wird von
PyMapping_Size()undPyObject_Size()verwendet und hat dieselbe Signatur. Dieser Slot darf aufNULLgesetzt werden, wenn das Objekt keine festgelegte Länge hat.
-
binaryfunc PyMappingMethods.mp_subscript¶
The corresponding slot ID
Py_mp_subscriptis part of the Stable ABI.Diese Funktion wird von
PyObject_GetItem()undPySequence_GetSlice()verwendet und hat dieselbe Signatur wiePyObject_GetItem(). Dieser Slot muss gefüllt sein, damit die FunktionPyMapping_Check()1zurückgibt. Andernfalls darf erNULLsein.
-
objobjargproc PyMappingMethods.mp_ass_subscript¶
The corresponding slot ID
Py_mp_ass_subscriptis part of the Stable ABI.Diese Funktion wird von
PyObject_SetItem(),PyObject_DelItem(),PySequence_SetSlice()undPySequence_DelSlice()verwendet. Sie hat dieselbe Signatur wiePyObject_SetItem(), v darf aber auch aufNULLgesetzt werden, um ein Element zu löschen. Ist dieser SlotNULL, unterstützt das Objekt das Zuweisen und Löschen von Elementen nicht.
Strukturen für Sequenzobjekte¶
-
type PySequenceMethods¶
Diese Struktur enthält Zeiger auf die Funktionen, über die ein Objekt das Sequenzprotokoll umsetzt.
-
lenfunc PySequenceMethods.sq_length¶
The corresponding slot ID
Py_sq_lengthis part of the Stable ABI.Diese Funktion wird von
PySequence_Size()undPyObject_Size()verwendet und hat dieselbe Signatur. Sie dient außerdem dem Umgang mit negativen Indizes über die Slotssq_itemundsq_ass_item.
-
binaryfunc PySequenceMethods.sq_concat¶
The corresponding slot ID
Py_sq_concatis part of the Stable ABI.Diese Funktion wird von
PySequence_Concat()verwendet und hat dieselbe Signatur. Sie wird außerdem vom Operator+verwendet, nachdem die numerische Addition über den Slotnb_addversucht wurde.
-
ssizeargfunc PySequenceMethods.sq_repeat¶
The corresponding slot ID
Py_sq_repeatis part of the Stable ABI.Diese Funktion wird von
PySequence_Repeat()verwendet und hat dieselbe Signatur. Sie wird außerdem vom Operator*verwendet, nachdem die numerische Multiplikation über den Slotnb_multiplyversucht wurde.
-
ssizeargfunc PySequenceMethods.sq_item¶
The corresponding slot ID
Py_sq_itemis part of the Stable ABI.Diese Funktion wird von
PySequence_GetItem()verwendet und hat dieselbe Signatur. Sie wird außerdem vonPyObject_GetItem()verwendet, nachdem der Indexzugriff über den Slotmp_subscriptversucht wurde. Dieser Slot muss gefüllt sein, damit die FunktionPySequence_Check()1zurückgibt. Andernfalls darf erNULLsein.Mit negativen Indizes wird so umgegangen: Ist der Slot
sq_lengthgefüllt, wird er aufgerufen, und über die Länge der Sequenz wird ein positiver Index berechnet, der ansq_itemübergeben wird. Istsq_lengthNULL, wird der Index unverändert an die Funktion übergeben.
-
ssizeobjargproc PySequenceMethods.sq_ass_item¶
The corresponding slot ID
Py_sq_ass_itemis part of the Stable ABI.Diese Funktion wird von
PySequence_SetItem()verwendet und hat dieselbe Signatur. Sie wird außerdem vonPyObject_SetItem()undPyObject_DelItem()verwendet, nachdem das Zuweisen und Löschen von Elementen über den Slotmp_ass_subscriptversucht wurde. Dieser Slot darfNULLbleiben, wenn das Objekt das Zuweisen und Löschen von Elementen nicht unterstützt.
-
objobjproc PySequenceMethods.sq_contains¶
The corresponding slot ID
Py_sq_containsis part of the Stable ABI.Diese Funktion kann von
PySequence_Contains()verwendet werden und hat dieselbe Signatur. Dieser Slot darfNULLbleiben. In diesem Fall durchläuftPySequence_Contains()die Sequenz einfach, bis es eine Übereinstimmung findet.
-
binaryfunc PySequenceMethods.sq_inplace_concat¶
The corresponding slot ID
Py_sq_inplace_concatis part of the Stable ABI.Diese Funktion wird von
PySequence_InPlaceConcat()verwendet und hat dieselbe Signatur. Sie sollte ihren ersten Operanden ändern und zurückgeben. Dieser Slot darfNULLbleiben. In diesem Fall fälltPySequence_InPlaceConcat()aufPySequence_Concat()zurück. Sie wird außerdem von der erweiterten Zuweisung+=verwendet, nachdem die numerische Addition an Ort und Stelle über den Slotnb_inplace_addversucht wurde.
-
ssizeargfunc PySequenceMethods.sq_inplace_repeat¶
The corresponding slot ID
Py_sq_inplace_repeatis part of the Stable ABI.Diese Funktion wird von
PySequence_InPlaceRepeat()verwendet und hat dieselbe Signatur. Sie sollte ihren ersten Operanden ändern und zurückgeben. Dieser Slot darfNULLbleiben. In diesem Fall fälltPySequence_InPlaceRepeat()aufPySequence_Repeat()zurück. Sie wird außerdem von der erweiterten Zuweisung*=verwendet, nachdem die numerische Multiplikation an Ort und Stelle über den Slotnb_inplace_multiplyversucht wurde.
Strukturen für Pufferobjekte¶
-
type PyBufferProcs¶
Diese Struktur enthält Zeiger auf die Funktionen, die das Puffer-Protokoll verlangt. Das Protokoll legt fest, wie ein exportierendes Objekt seine internen Daten für verbrauchende Objekte zugänglich machen kann.
-
getbufferproc PyBufferProcs.bf_getbuffer¶
The corresponding slot ID
Py_bf_getbufferis part of the Stable ABI seit Version 3.11.Die Signatur dieser Funktion lautet:
int (PyObject *exporter, Py_buffer *view, int flags);
Behandelt eine Anfrage an exporter, view so zu füllen, wie flags es angibt. Abgesehen von Punkt (3) MUSS eine Umsetzung dieser Funktion diese Schritte ausführen:
Prüfen, ob die Anfrage erfüllt werden kann. Wenn nicht,
BufferErrorauslösen,view->objaufNULLsetzen und-1zurückgeben.Die angefragten Felder füllen.
Einen internen Zähler für die Anzahl der Exporte erhöhen.
view->objauf exporter setzen undview->objerhöhen.0zurückgeben.
Thread-Sicherheit:
Im Build mit freien Threads müssen Umsetzungen sicherstellen:
Das Erhöhen des Exportzählers in Schritt (3) ist atomar.
Die zugrunde liegenden Pufferdaten bleiben gültig und an einer unveränderlichen Speicherstelle, solange Exporte bestehen.
Bei Objekten, die sich in der Größe ändern oder neu belegen lassen (wie
bytearray), wird der Exportzähler vor solchen Vorgängen atomar geprüft, und es wirdBufferErrorausgelöst, wenn Exporte bestehen.Die Funktion lässt sich sicher gleichzeitig aus mehreren Threads aufrufen.
Siehe auch Threadsicherheit bei memoryview-Objekten zu den Zusagen zur Thread-Sicherheit von
memoryview-Objekten auf Python-Ebene.Ist exporter Teil einer Kette oder eines Baums von Pufferanbietern, sind zwei grundlegende Vorgehensweisen möglich:
Weiterexport: Jedes Mitglied des Baums tritt als exportierendes Objekt auf und setzt
view->objauf eine neue Referenz auf sich selbst.Umleitung: Die Pufferanfrage wird an das Wurzelobjekt des Baums umgeleitet. Hier ist
view->objeine neue Referenz auf das Wurzelobjekt.
Die einzelnen Felder von view sind im Abschnitt Pufferstruktur beschrieben, die Regeln, wie ein Exporteur auf bestimmte Anfragen reagieren muss, stehen im Abschnitt Arten von Pufferanfragen.
Aller Speicher, auf den die Struktur
Py_bufferzeigt, gehört dem Exporteur und muss gültig bleiben, solange noch Verbraucher vorhanden sind.format,shape,strides,suboffsetsundinternalsind für den Verbraucher nur lesbar.PyBuffer_FillInfo()bietet einen einfachen Weg, einen schlichten Bytes-Puffer zugänglich zu machen und dabei alle Arten von Anfragen richtig zu behandeln.PyObject_GetBuffer()ist die Schnittstelle für den Verbraucher, die diese Funktion umhüllt.
-
releasebufferproc PyBufferProcs.bf_releasebuffer¶
The corresponding slot ID
Py_bf_releasebufferis part of the Stable ABI seit Version 3.11.Die Signatur dieser Funktion lautet:
void (PyObject *exporter, Py_buffer *view);
Behandelt eine Anfrage, die Ressourcen des Puffers freizugeben. Müssen keine Ressourcen freigegeben werden, darf
PyBufferProcs.bf_releasebufferNULLsein. Andernfalls führt eine gewöhnliche Umsetzung dieser Funktion diese wahlfreien Schritte aus:Einen internen Zähler für die Anzahl der Exporte verringern.
Ist der Zähler
0, allen zu view gehörenden Speicher freigeben.
Thread-Sicherheit:
Das Verringern des Exportzählers in Schritt (1) muss atomar sein.
Das Aufräumen der Ressourcen, wenn der Zähler null erreicht, muss atomar geschehen, weil die letzte Freigabe mit gleichzeitigen Freigaben anderer Threads um die Wette laufen kann und die Speicherfreigabe nur ein einziges Mal geschehen darf.
Der Exporteur MUSS das Feld
internalverwenden, um pufferspezifische Ressourcen zu verfolgen. Dieses Feld bleibt zugesichert unverändert, während ein Verbraucher dem Argument view eine Kopie des ursprünglichen Puffers übergeben DARF.Diese Funktion DARF
view->objNICHT verringern, weil das inPyBuffer_Release()automatisch geschieht (diese Vorgehensweise ist nützlich, um Referenzzyklen aufzubrechen).PyBuffer_Release()ist die Schnittstelle für den Verbraucher, die diese Funktion umhüllt.
Strukturen für Async-Objekte¶
Added in version 3.5.
-
type PyAsyncMethods¶
Diese Struktur enthält Zeiger auf die Funktionen, die nötig sind, um abwartbare Objekte und asynchrone Iteratoren umzusetzen.
Hier die Strukturdefinition:
typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; sendfunc am_send; } PyAsyncMethods;
-
unaryfunc PyAsyncMethods.am_await¶
The corresponding slot ID
Py_am_awaitis part of the Stable ABI seit Version 3.5.Die Signatur dieser Funktion lautet:
PyObject *am_await(PyObject *self);
Das zurückgegebene Objekt muss ein Iterator sein,
PyIter_Check()muss dafür also1zurückgeben.Dieser Slot darf auf
NULLgesetzt werden, wenn ein Objekt nicht abwartbar ist.
-
unaryfunc PyAsyncMethods.am_aiter¶
The corresponding slot ID
Py_am_aiteris part of the Stable ABI seit Version 3.5.Die Signatur dieser Funktion lautet:
PyObject *am_aiter(PyObject *self);
Muss ein Objekt zurückgeben, das ein asynchroner Iterator ist. Einzelheiten stehen unter
__anext__().Dieser Slot darf auf
NULLgesetzt werden, wenn ein Objekt das Protokoll für asynchrone Iteration nicht umsetzt.
-
unaryfunc PyAsyncMethods.am_anext¶
The corresponding slot ID
Py_am_anextis part of the Stable ABI seit Version 3.5.Die Signatur dieser Funktion lautet:
PyObject *am_anext(PyObject *self);
Muss ein abwartbares Objekt zurückgeben. Einzelheiten stehen unter
__anext__(). Dieser Slot darf aufNULLgesetzt werden.
-
sendfunc PyAsyncMethods.am_send¶
The corresponding slot ID
Py_am_sendis part of the Stable ABI seit Version 3.10.Die Signatur dieser Funktion lautet:
PySendResult am_send(PyObject *self, PyObject *arg, PyObject **result);
Einzelheiten stehen unter
PyIter_Send(). Dieser Slot darf aufNULLgesetzt werden.Added in version 3.10.
Typedefs für Slot-Typen¶
-
typedef PyObject *(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems)¶
- Teil der Stable ABI.
Diese Funktion soll die Speicherbelegung von der Speicherinitialisierung trennen. Sie sollte einen Zeiger auf einen Speicherblock zurückgeben, der für die Instanz lang genug und passend ausgerichtet und mit Nullen initialisiert ist, bei dem aber
ob_refcntauf1undob_typeauf das Typargument gesetzt ist. Isttp_itemsizedes Typs ungleich null, sollte das Feldob_sizedes Objekts mit nitems initialisiert werden, und die Länge des belegten Speicherblocks solltetp_basicsize + nitems*tp_itemsizesein, aufgerundet auf ein Vielfaches vonsizeof(void*). Andernfalls wird nitems nicht verwendet, und die Länge des Blocks solltetp_basicsizesein.Diese Funktion sollte keine weitere Initialisierung der Instanz vornehmen, auch keinen zusätzlichen Speicher belegen. Das sollte
tp_newerledigen.
-
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 des Objekts zurück.
-
typedef int (*setattrfunc)(PyObject *self, char *attr, PyObject *value)¶
- Teil der Stable ABI.
Setzt den Wert des benannten Attributs des Objekts. Das Argument für den Wert 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 des Objekts zurück.
Siehe
tp_getattro.
-
typedef int (*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value)¶
- Teil der Stable ABI.
Setzt den Wert des benannten Attributs des Objekts. Das Argument für den Wert 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¶
Hier einige einfache Beispiele für Python-Typdefinitionen. Sie enthalten gängige Verwendungen, auf die du stoßen wirst. Manche zeigen knifflige Sonderfälle. Weitere Beispiele, praktische Hinweise und eine Einführung stehen unter Defining Extension Types: Tutorial und Defining Extension Types: Assorted Topics.
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,
};
Du wirst möglicherweise auch älteren Code finden (besonders in der CPython-Codebasis), der einen ausführlicheren Initialisierer verwendet:
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-Dictionaries 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_GenericAlloc,
.tp_dealloc = (destructor)myobj_dealloc,
.tp_repr = (reprfunc)myobj_repr,
.tp_hash = (hashfunc)myobj_hash,
.tp_richcompare = PyBaseObject_Type.tp_richcompare,
};
Eine str-Unterklasse, von der sich keine Unterklassen bilden lassen und die sich nicht aufrufen lässt, um Instanzen zu erzeugen (die also zum Beispiel eine eigene Fabrikfunktion verwendet), mithilfe 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 veränderlicher 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 *),
};