Bevor wir über die Erstellung und das Verhalten von Objekten sprechen, werfen wir zunächst einen Blick auf Typobjekte. Python ist eine schwach typisierte Sprache. Dies bedeutet jedoch nicht, dass es in Python keine speziellen Objekte gibt Behandeln Sie den Typ des Objekts, den wir Typobjekt nennen. Wenn Sie den Typ des Objekts nicht kennen, können Sie keinen Speicherplatz für das Objekt freigeben, da die Größe des belegten Speichers die Metainformation des Objekts ist Die grundlegenden Informationen des Objekts hängen eng mit dem Typ des Objekts zusammen. Öffnen Sie daher die Datei object.h im Include-Ordner im Python-Quellcode und sehen Sie sich den Quellcode von PyTypeObject ungefähr in Zeile 324 an:
typedef struct _typeobject {
PyObject_VAR_HEAD
const char *tp_name; /* Zum Drucken im Format „
Py_ssize_t tp_basicsize, tp_itemsize; /* Für Zuweisung */
/* Methoden zur Implementierung von Standardoperationen */
Destruktor tp_dealloc;
printfunc tp_print;
getattrfunc tp_getattr;
/* Methodensuiten für Standardklassen */
PySequenceMethods *tp_as_sequence; * Weitere Standardoperationen (hier für Binärkompatibilität) */
hashfunc tp_hash;
ternaryfunc tp_str;
getattrofunc tp_getattro; 🎜>
/* Funktionen für den Zugriff auf Objekte als Eingabe/Ausgabe buffer */
PyBufferProcs *tp_as_buffer; /* Flags zum Definieren des Vorhandenseins optionaler/erweiterter Funktionen */
long tp_flags; */
/* Zugewiesene Bedeutung in Release 2.0 */
/* Funktion für alle zugänglichen Objekte aufrufen */
traverseproc tp_traverse;
/* Referenzen auf enthaltene Objekte löschen * /
query tp_clear;
/* Zugewiesene Bedeutung in Version 2.1 */
/* Rich-Vergleiche */
Richcmpfunc tp_richcompare;
/* Schwacher Referenz-Enabler */
Py_ssize_t tp_weaklistoffset;
/* Hinzugefügt in Version 2.2 */
/* Iteratoren */
getiterfunc tp_iter;
/ * Attributdeskriptor und Unterklassen */
struct PyMethodDef *tp_methods;
struct PyGetSetDef *tp_getset;
PyObject *tp_dict; c tp_descr_get;
descrsetfunc tp_descr_set;
initproc tp_init; new;
freefunc tp_free; /* Low-Level-Routine für freien Speicher tp_is_gc; / * Für PyObject_IS_GC */
PyObject *tp_bases; /* Methodenauflösungsreihenfolge */
PyObject *tp_subclasses;
destructor tp_del;
/* Typattribut-Cache-Versions-Tag explizit initialisiert */
Py_ssize_t tp_allocs;
Py_ssize_t tp_maxalloc;
#endif
Der obige Code ist mit mehr als 100 Zeilen für eine Struktur sehr lang, aber die enthaltenen Informationen sind hauptsächlich in die folgenden vier Kategorien unterteilt:
1. Typname, tp_name, wird hauptsächlich intern in Python und beim Debuggen zur Identifizierung verwendet Objekte Der Typ des Objekts;
2. tp_basicsize und tp_itemsize, Informationen über die Größe des für die Erstellung dieses Objekttyps zugewiesenen Speicherplatzes;
3 Funktionen wie tp_base;
4.
Wichtige Punkte 1. Erstellung von Objekten:
Es gibt zwei Hauptmethoden zum Erstellen von Objekten in Python: Python C API und PyInt_Type.
Python C API ermöglicht Benutzern die Interaktion mit Python aus der C-Umgebung. Es gibt zwei APIs, eine ist AOL (Abstract Object Layer), eine generische API, und die andere ist COL (Concrete Object Layer). eine Typ-API; AOL Alle haben die Form PyObject_***, die auf jedes Python-Objekt angewendet werden kann. Der Ausdruck wird im Allgemeinen wie folgt ausgedrückt: PyObject* intObj = PyObject_new(PyObject,&PyInt_Type), und die COL-API lautet im Allgemeinen wie folgt : PyObject* intObj = PyInt_FromLong (1000); Wir haben ein 1000-Integer-Objekt erstellt.
Unabhängig davon, welche Python-C-API verwendet wird, wird Python irgendwann Speicher direkt zuweisen, da dies alles integrierte Python-Objekte sind, und wenn wir selbst eine Klasse definieren, wie zum Beispiel: Klasse MySelf (Objekt), für den Typ MySelf, Python wird nicht mit der API erstellt, aber Python erstellt ein Instanzobjekt über das Typobjekt, das MySelf entspricht. Das Typobjekt von MySelf ist Objekt, sodass Python über Objekt ein Instanziierungsobjekt von MySelf erstellt. Wir führen den folgenden Code aus:
class A(object):
pass
a = A()
type(a)
A.__base__
Das Ergebnis ist wie folgt folgt:
Screenshot 14.06.2014 um 12.01.15 Uhr
Objektverhalten:
Es gibt drei sehr wichtige Gruppen von Operationsfamilien in den Operationsinformationen des Objekts: tp_as_number, tp_as_sequence, tp_as_mapping Verweist jeweils auf die Funktionsfamilie PyNumberMethods, PySequenceMethods und PyMappingMethods. Für ein Objekt kann er alle Operationen in drei Funktionsfamilien gleichzeitig definieren, das heißt, das Objekt kann die Eigenschaften numerischer Objekte und die Eigenschaften zugeordneter Objekte anzeigen. Der Code lautet wie folgt:
class MyInt(int) :
def __getitem__(self,key):
return key+str(self)
a = MyInt(1)
b = MyInt(2)
print a+b
print a['key']
Das laufende Ergebnis ist:
1
2
3
key1
Lassen Sie uns zum Schluss darüber sprechen Typ des Typobjekts. Der Objekttyp ist auch ein Objekt. Was ist also der Typ dieses Objekts? Zunächst lässt sich feststellen, dass er auch ein Objekt ist. Wir nennen sie Typen von Typen. Das ist sehr, sehr, sehr wichtig. Es handelt sich um die PyType_Type-Struktur im Quellcode. Diese befindet sich in der Datei typeobject.c im Objektordner. Der Quellcode lautet wie folgt:
PyTypeObject PyType_Type = {
PyVarObject_HEAD_INIT( / 🎜> sizeof(PyMemberDef), /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */
0, /* tp_getattr */
0, /* tp_setattr */
0, (reprfunc)type_repr, /* tp_repr */
0, /* tp_as_number */
. /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)_Py_HashPointer, /* tp_hash */
(ternaryfunc)type_call, /* tp_call */
0, /* tp_str */
. getattrofunc)type_getattro, /* tp_getattro */
(setattrofunc)type_setattro, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TYPE_SUBCLASS, /* tp_flags */
type_doc, /* tp_doc */
(traverseproc)type_traverse, /* tp_traverse */
(Anfrage)type_clear, /* tp_clear */ type_richcompare, /* tp_richcompare */
offsetof(PyTypeObject, tp_weaklist), /* tp_weaklistoffset */
0, /* tp_iter. */
0, /* tp_iternext */
type_methods, /* tp_methods */
type_members, /* tp_members */
type_getsets, /* tp_getset */
0, /* tp_base */
. 0, /* tp_dict */
0, /* tp_descr_get */
0, */
offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */
type_init, /* tp_init */
/* tp_alloc */
type_new, /* tp_new */ /* tp_free. */ };
呵呵,这个看起来很复杂,PyInt_Type和PyType_Type之间如何联系起来的?就是前面博客中所说的引用计数器,一个整数对象运行时如下图所示:
Screenshot 2014-06- 14 am 32. Januar 2009