Die Frage, die ich stellen werde, scheint ein Duplikat von Pythons Verwendung von __new__ und __init__ zu sein. Trotzdem ist mir immer noch unklar, was genau der praktische Unterschied zwischen __new__und __init__ist.
Bevor Sie mir sagen, dass dies __new__zum Erstellen von Objekten und __init__zum Initialisieren von Objekten dient, lassen Sie mich klar sein: Ich verstehe das. Tatsächlich ist diese Unterscheidung für mich ganz natürlich, da ich Erfahrung in C ++ habe, wo wir eine neue Platzierung haben , die in ähnlicher Weise die Objektzuweisung von der Initialisierung trennt.
Das Python C API-Tutorial erklärt es folgendermaßen:
Das neue Mitglied ist für das Erstellen (im Gegensatz zum Initialisieren) von Objekten des Typs verantwortlich. Es wird in Python als
__new__()Methode verfügbar gemacht. ... Ein Grund für die Implementierung einer neuen Methode besteht darin, die Anfangswerte der Instanzvariablen sicherzustellen .
Also, ja - ich verstehe , was es __new__tut, aber trotzdem verstehe ich immer noch nicht, warum es in Python nützlich ist. Das angegebene Beispiel besagt, dass __new__dies nützlich sein kann, wenn Sie "die Anfangswerte von Instanzvariablen sicherstellen" möchten. Ist das nicht genau das, was __init__wir tun werden?
Im C API-Tutorial wird ein Beispiel gezeigt, in dem ein neuer Typ ("Noddy" genannt) erstellt und die __new__Funktion des Typs definiert wird. Der Noddy-Typ enthält ein Zeichenfolgenelement mit dem Namen first, und dieses Zeichenfolgenelement wird wie folgt mit einer leeren Zeichenfolge initialisiert:
static PyObject * Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
.....
self->first = PyString_FromString("");
if (self->first == NULL)
{
Py_DECREF(self);
return NULL;
}
.....
}
Beachten Sie, dass __new__wir ohne die hier definierte Methode verwenden müssten PyType_GenericNew, die einfach alle Instanzvariablenelemente auf NULL initialisiert. Der einzige Vorteil der __new__Methode besteht darin, dass die Instanzvariable im Gegensatz zu NULL als leere Zeichenfolge beginnt. Aber warum ist das jemals nützlich, denn wenn wir sicherstellen wollten, dass unsere Instanzvariablen auf einen Standardwert initialisiert werden, hätten wir das einfach in der __init__Methode tun können ?
__new__ist kein Boilerplate, da sich das Boilerplate nie ändert. Manchmal müssen Sie diesen bestimmten Code durch etwas anderes ersetzen.