2016-05-23 9 views
11

Wenn ich versuche, die magische Methode __eq__ zu überschreiben, und super zu verwenden, um die Basis-Methode in object gefunden zu bekommen, erhalte ich einen Fehler. Es gibt keine Möglichkeit dies ein Fehler ist, aber es fühlt sich sicher wie ein:'Super' Objekt hat kein Attribut '__eq__'

class A(object): 
    def __eq__(self, other): 
     return super(A, self).__eq__(other) 
A() == 0 

# raises AttributeError: 'super' object has no attribute '__eq__' 

Diese unintuitive ist, weil object.__eq__ existiert, aber für class A(object): pass nicht. Wenn ich mich nicht irre __eq__ zu einem is überprüfen, so dass die Abhilfe hier sein kann, aber is statt super ist nicht mixin freundlich. Diese Route ist in meinem Fall in Ordnung, in anderen aber nicht.

Irgendwelche Vorschläge oder Informationen darüber, warum __eq__ auf diese Weise funktioniert, wäre großartig.

+1

Der Fehler wird in 2.7 ausgelöst, aber nicht in 3.5 ausgelöst –

+1

Nein, "Objekt" unterstützt nicht "__eq__" auf ** Instanzen ** ... versuchen Sie 'object() .__ eq__', es wird ein 'AttributeError' ausgelöst '... stattdessen' object .__ eq__ ist (wahrscheinlich) eine Klassenmethode um zu überprüfen, ob Typen identisch sind (zB 'object .__ eq __ (object)') – donkopotamus

+0

@donkopotamus: Das wird dein Objekt nicht mit 'other' vergleichen; Es wird ein neu erstelltes "leeres" Objekt mit "anderes" vergleichen. – BrenBarn

Antwort

4

Wie in Wills Antwort erwähnt, object() nicht wirklich __eq__ implementieren überhaupt für Instanzen (in Python 2.7).

Sie werden durch die Tatsache täuschen, daß object.__eq__ existiert, zu glauben, es muss ein Verfahren sein, das des Objekts, wenn Instanzen überprüft gleich sind

Stattdessen object.__eq__ tatsächlich eine Klassenmethode ist, von type geerbt, dh Wird verwendet, um zu prüfen, ob die Typen gleich sind.

Das heißt, um Ausdrücke wie object == int und object == object zu behandeln.

2

Dies ist, weil object() nicht wirklich eine __eq__() implementieren. Die „default“ hier wäre:

class A(object): 
    def __eq__(self, other): 
     if self is other: 
      return True 

     return self == other 

Aber wenn das, was Sie gearbeitet haben sind dem Versuch, würden Sie eigentlich, ob die self Instanz other entsprach der Elternklasse überprüft werden. Und es ist das gleiche Objekt (self), also würde es. Also das nächste Äquivalent des Codes wäre tatsächlich:

class A(object): 
    def __eq__(self, other): 
     if self is other: 
      return True 

     return super(A, self) == other 
+2

Wie ich eine zuvor gelöschte Antwort kommentiert, Ihr zweites Beispiel erbt das Standardverhalten nicht, denn wenn Sie 'x = A()' eingeben, gibt 'x == x' False zurück. (Ihr erstes Beispiel verursacht eine unendliche Rekursion.) – BrenBarn

+0

Danke, das sollte in meinem Edit behoben werden. – Will