Heim > Artikel > Backend-Entwicklung > __new__ und __init__ in Python2, Klassen im neuen Stil und klassische Klassen
In python2.x werden Klassen, die vom Objekt erben, als Klassen neuen Stils bezeichnet (z. B. Klasse A(object)) und Klassen, die nicht vom Objekt erben, werden als klassische Klassen bezeichnet (z. B. Klasse A())
Die Hauptunterschiede zwischen Klassen neuen Stils und klassischen Klassen sind die folgenden Punkte:
1. Klassenobjekte neuen Stils können ihre eigenen Typen direkt über das __class__-Attribut erhalten: Typ
2. Vererbungssuche Die Reihenfolge hat sich geändert. Bei der klassischen Klassenmehrfachvererbung lautet die Attributsuchreihenfolge: Gehen Sie zuerst tief in die linke Seite des Vererbungsbaums, gehen Sie dann zurück und beginnen Sie mit der Suche nach der rechten Seite (dh der Tiefe). -erste Suche); in der neuen Klasse Mehrfachvererbungsattribut-Suchreihenfolge: zuerst horizontal suchen, dann nach oben verschieben
Klassische Klasse: Die Suchreihenfolge ist (D,B, A,C)
>>> class A: attr = 1 ... >>> class B(A): pass ... >>> class C(A): attr = 2 ... >>> class D(B,C): pass ... >>> x = D() >>> x.attr 1
Das Suchverfahren für die Klassenvererbung im neuen Stil ist breit angelegt
Klassen im neuen Stil: die Suche Reihenfolge ist (D,B,C,A)
>>> class A(object): attr = 1 ... >>> class B(A): pass ... >>> class C(A): attr = 2 ... >>> class D(B,C): pass ... >>> x = D() >>> x.attr 2
3. Klassen im neuen Stil hinzugefügt Mit dem integrierten Attribut __slots__ kann der Typ der Instanzattribute festgelegt werden der durch __slots__ angegebene Bereich.
4. Die Klasse im neuen Stil fügt die Methode __getattribute__ hinzu
5. Die Klasse im neuen Stil verfügt über eine integrierte Methode __new__, während die klassische Klasse keine Methode __new__, sondern nur eine hat __init__-Methode
Hinweis: Die Standardklassen in Python 2. Der Vorfahre der Klasse), es besteht keine Notwendigkeit, das Objekt explizit zu erben (Sie können eine klassische Klasse gemäß der Definition einer klassischen Klasse schreiben und diese verwenden dir-Funktion, um es in den Versionen python2.x bzw. 3.x zu überprüfen.
Zum Beispiel: class A():
durch durch (dir(A))
Sie werden feststellen, dass es unter 2.x keine __new__-Methode gibt, aber unter 3.x. 🎜>
Lassen Sie uns über den Unterschied zwischen der __new__-Methode und __init__ sprechen: Beim Erstellen einer Instanz einer Klasse Wenn in Python die Klasse über eine __new__-Methode verfügt, wird __new_ zuerst aufgerufen. _Methode, __new__-Methode akzeptiert die aktuell instanziierte Klasse als ersten Parameter (der Typ dieses Parameters ist Typ, der eine wichtige Rolle bei der interaktiven Programmierung zwischen C und Python spielt). Wenn Sie interessiert sind, können Sie nach relevanten Informationen suchen. Der Rückgabewert ist die von dieser Erstellung generierte Instanz, die der erste Parameter self in der bekannten Methode __init__ ist Diese Instanz? Beachten Sie, dass diejenigen mit __new__-Methoden Nachkommen der Objektklasse sind. Wenn wir also die __new__-Methode selbst überschreiben möchten (beachten Sie, dass wir die __new__-Methode der übergeordneten Klasse verwenden). Wenn die übergeordnete Klasse keine Instanz hat, können Sie diese Instanz erhalten, indem Sie die Methode __new__ des Objekts aufrufen (dies entspricht im Grunde dem Standardmechanismus in Python), z als:
Das Ausführen des obigen Codes erhält die folgende Ausgabe:
class display(object): def __init__(self, *args, **kwargs): print("init") def __new__(cls, *args, **kwargs): print("new") print(type(cls)) return object.__new__(cls, *args, **kwargs) a=display()neu
init
So können wir die folgende Schlussfolgerung ziehen:
Im Instanzerstellungsprozess wird die Methode __new__ vor der Methode __init__ aufgerufen, und ihr erster Parametertyp ist Typ.
Die obige Ausgabe lautet:
class another(object): def __new__(cls,*args,**kwargs): print("newano") return object.__new__(cls, *args, **kwargs) class display(object): def __init__(self, *args, **kwargs): print("init") def __new__(cls, *args, **kwargs): print("newdis") print(type(cls)) return another.__new__(cls, *args, **kwargs) a=display()
Alles, was wir gefunden haben, ist, dass __new__ und __init__ eine solche Beziehung haben, dass __init__ das Rohmaterial selbst für die Produktion bereitstellt (aber es garantiert nicht, dass die Quelle von Dieses Rohmaterial ist authentisch. Es verwendet eine andere nicht verwandte Klasse (Methodenklasse __new__), um diese Instanz zu erhalten. __init__ verwendet die von __new__ angegebenen Rohmaterialien, um dieses Objekt zu vervollständigen (obwohl es nicht weiß, ob diese Rohmaterialien authentisch sind).
newdis <class 'type'> newano init