Was man fragen kann, und einfach durchgeführt werden.Zum Beispiel:
Also der Grund, dass super mit magischen Methoden arbeitet, ist nicht, weil es nicht möglich ist. Der Grund muss woanders liegen. Ein Grund ist, dass dies den Vertrag von Gleichgestellten verletzen würde (==
). Das Gleiche ist unter anderem symmetrisch. Das heißt, wenn a == b
wahr ist, muss auch b == a
wahr sein. Das bringt uns in eine knifflige Situation, wo super(self, CurrentClass) == self
, aber self != super(self, CurrentClass)
z.
class dundersuper(super):
def __eq__(self, other):
return self.__eq__(other)
super = dundersuper
class A:
def self_is_other(self, other):
return super() == other # a.k.a. object.__eq__(self, other) or self is other
def __eq__(self, other):
"""equal if both of type A"""
return A is type(self) and A is type(other)
class B:
def self_is_other(self, other):
return other == super() # a.k.a object.__eq__(other, super()), ie. False
def __eq__(self, other):
return B is type(self) and B is type(other)
assert A() == A()
a = A()
assert a.self_is_other(a)
assert B() == B()
b = B()
assert b.self_is_other(b) # assertion fails
Ein weiterer Grund ist, dass, sobald Super getan sucht es das Objekt MRO gegeben hat, es dann zu geben, hat sich eine Chance, die gewünschte Attribut zu liefern - Super-Objekte sind nach wie vor ein Objekte in ihrem eigenen Recht - wir sollten Sie können nach Gleichheit mit anderen Objekten suchen, nach Zeichenkettenrepräsentationen fragen und das Objekt und die Klasse untersuchen, mit denen Super arbeitet. Dies führt zu einem Problem, wenn die Methode dunder für das Superobjekt verfügbar ist, nicht jedoch für das Objekt, das das veränderbare Objekt darstellt. Zum Beispiel:
class dundersuper(super):
def __add__(self, other):
return self.__add__(other)
def __iadd__(self, other):
return self.__iadd__(other)
super = dundersuper
class MyDoubleList(list):
"""Working, but clunky example."""
def __add__(self, other):
return MyDoubleList(super() + 2 * other)
def __iadd__(self, other):
s = super()
s += 2 * other # can't assign to the result of a function, so we must assign
# the super object to a local variable first
return s
class MyDoubleTuple(tuple):
"""Broken example -- iadd creates infinite recursion"""
def __add__(self, other):
return MyDoubleTuple(super() + 2 * other)
def __iadd__(self, other):
s = super()
s += 2 * other
return s
Mit der Liste Beispiel __iadd__
die Funktion mehr haben könnte einfach als
def __iadd__(self, other):
return super().__iadd__(other)
Mit dem Tupel Beispiel geschrieben uns in unendliche Rekursion fallen, ist dies, weil tuple.__iadd__
existiert nicht. Daher wird beim Nachschlagen des Attributs __iadd__
an einem Super-Objekt das tatsächliche Super-Objekt auf ein __iadd__
Attribut überprüft (das existiert). Wir bekommen diese Methode und rufen sie auf, wodurch der gesamte Prozess erneut gestartet wird. Wenn wir keine __iadd__
Methode auf Super geschrieben hätten und super().__iadd__(other)
benutzt hätten, wäre das niemals passiert. Stattdessen erhalten wir eine Fehlermeldung über ein Super-Objekt ohne das Attribut __iadd__
. Etwas kryptisch, aber weniger als eine unendliche Stapelspur.
Der Grund, warum Super funktioniert nicht mit magischen Methoden ist, dass es mehr Probleme schafft, als es löst.
http://stackoverflow.com/questions/12047847/super-object-not-calling-getattr –
Auch hilfreich: https://docs.python.org/3/reference/datamodel.html#special-method- Nachschlagen – wim