was bedeutet `super()` in `__new__`
Hinweis: Teil eines flyweight-Implementierung mit Python
import weakref
class CarModel:
_models = weakref.WeakValueDictionary()
def __new__(cls, model_name, *args, **kwargs):
model = cls._models.get(model_name)
if not model:
model = super().__new__(cls)
cls._models[model_name] = model
return model
def __init__(self, model_name, air=False):
if not hasattr(self, "initted"):
self.model_name = model_name
self.air = air
self.initted=True
Frage 1> was ist super()
bedeuten? Bedeutet es die Eltern-Klasse CarModel
?
Frage 2> ich habe auch Schwierigkeiten zu verstehen, wie die Funktion __new__
funktioniert? Insbesondere die folgende Zeile.
model = super().__new__(cls)
Beschreibung für __new__
:
Konstruktor-Funktion aufgerufen wird
__new__
im Gegensatz zu__init__
, und
akzeptiert genau ein argument, die Klasse, die konstruiert wird (es
wird aufgerufen, bevor das Objekt erstellt wird, so dass es kein selbst gibt,
argument). Es hat auch zur Rückkehr des neu erstellten Objekts.
- basiert auf der Dokument,
__new__()
gibt eine Instanzcls
. warum der codemodel = super().__new__(cls)
im OP erstellen eine Instanz dercls
? Wie funktioniert die super-Klasse von CarModel wissen, wie man erstellen Sie eine Instanz der Unterklasse? - Das wäre eine große Frage ALSO auf eigene (falls es nicht schon gefragt worden). Die kurze Antwort ist, dass Sie übergeben Sie die aktuelle Klasse mit der
cls
parameter. Letztendlich gibt es keinen Weg, um tatsächlich eine neue Instanz erstellen, ohne aufzuschieben, den ganzen Weg zurück zuobject.__new__
, weil Python besitzt keine Anweisung für die "Zuweisung einer Instanz". Aberobject.__new__
weiß, zum erstellen einer Instanz der Klasse übergeben (das wird auch eine Instanz vonobject
, denn alles ist eine Instanz vonobject
).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Beginnen mit
super()
an sich ist einfach nur die Kurzform fürsuper(A, B)
, woA
ist die Klasse, worin der code Auftritt, undB
ist das erste argument der Funktion, in der der code vorkommt; also in deinem speziellen Fallsuper().__new__(cls)
erweitert, umsuper(CarModel, cls).__new__(cls)
.Wiederum
super(T, O)
gibt eine "super-Objekt". Um zu verstehen, was ein super-Objekt gibt, müssen Sie verstehen, wie-Attribut Referenzen auf Instanzen und Klassen arbeiten in Python.Vorausgesetzt, es ist kein
__getattr__
oder__getattribute__
Methoden beteiligt sind, verweisen auf AttributA
auf ein ObjektO
(das heißt, die BewertungO.A
odergetattr(O, "A")
) erfolgt durch die folgenden Schritte:"A"
definiert ist, inO
's Beispiel dict (O.__dict__
), dann wird der Wert auf das dict zurückgegeben wird, direkt, genau so wie er ist.O
's Methode der Auflösung Bestellung überprüft wiederum, auf der Suche nach"A"
in jedem Ihrer dicts. Wenn gefunden, rufen Sie den WertD
.D
wiederum nicht definiert ein__get__
, dann wird es zurückgegeben, wie es ist. Wenn es das tut, aber dannD
bezeichnet als "Deskriptor", und seine__get__
Methode wird aufgerufen, mitO
als erstes argument, undtype(O)
als das zweite argument.Eines Attributs Referenz auf eine Klasse arbeitet etwa die gleiche, wobei die Klasse die Referenz für die Instanz, mit den folgenden unterschieden:
__get__
Methode wird aufgerufen, mitNone
als erstes argument, und die Klasse, auf das verwiesen wird, als die zweite.Python verwendet Deskriptoren zu implementieren, die solche Dinge wie Instanzmethoden, Klassenmethoden, statische Methoden und Eigenschaften.
Einen super-Objekt erstellt, mit
super(T, O)
, dann ist a (built-in) - Objekt mit einem__getattribute__
Methode, die aufgerufen wird, auf jeden Attribut-Referenz auf, und sucht das Attribut in den dicts der nur Klassen, die folgenden T inO
's MRO. Der Wert, den es findet, ruft es__get__
wie gewohnt.Der Prozess ist ein wenig komplexer, so als Beispiel, hier ist, wie es funktionieren würde für Ihren spezifischen Fall. Da
CarModel
definiert ist, wie es ist, MRO ist[CarModel, object]
.super().__new__(cls)
erweitert, umsuper(CarModel, cls).__new__(cls)
, wie oben beschrieben.super(CarModel, cls)
ausgewertet ergeben ein super-ObjektS
."__new__"
aufS
(entspricht der Aufrufgetattr(S, "__new__")
im Python-code).S
wurde auf derCarModel
Klasse, es berücksichtigt die folgenden KlassenCarModel
im MRO vonCarModel
, und findet"__new__"
im dict derobject
Klasse selbst. Seinen Wert, eine statische Methode, hat eine__get__
Methode, die aufgerufen wird, mit den Argumenten, dieNone
undcls
. Da__new__
ist eine statische Methode, die__get__
Methode gibt einfach die Funktion, wie es ist, unverändert. Dahersuper(CarModel, cls).__new__
ist genau das gleiche wieobject.__new__
.object.__new__
) aufgerufen, wobei dercls
argument, wocls
ist wahrscheinlichCarModel
schließlich eine neue Instanz derCarModel
Klasse.Ich hoffe das war alles verständlich.
(Der Vollständigkeit halber, sollte erwähnt werden, dass die tatsächliche
__new__
Funktion auf derobject
Klasse ist nicht wirklich eine statische Methode, sondern eine spezielle integrierte Funktion, die hat einfach keine__get__
Methode überhaupt, aber seit der__get__
Methode auf statische Methoden einfach nur wieder die Funktion, die Sie definiert wurden, mit, der Effekt ist der gleiche.)super(class1, class2)
, wie funktioniertsuper
verwendenclass1
undclass2
?super()
zur Angabe des übergeordneten (d.h. der parent-Klasse, von der Sie Erben).__new__
ist eine Methode, die aufgerufen wird, um erstellen Sie eine neue Instanz der Klasse, wenn es definiert ist.super(class1, class2)
, wie funktioniertsuper
verwendenclass1
undclass2
?Ich glaube, Sie sind mit Python ist3, wo der super-muss nicht gestellt werden mit der gleichen Klasse Namen. Super bezieht sich auf den Basis-Klassen der aktuellen Klasse und hat die richtige Methode Auflösung Um für Sie zum aufrufen der Methode, von der richtigen Basis-Klasse.
__new__
ist die Methode, die aufgerufen wird, eine Instanz zu schaffen. Es ist die erste Schritt in der Instanz-Erstellung.super(class1, class2)
, wie funktioniertsuper
verwendenclass1
undclass2
?