2016-05-23 19 views
11

Quando provo a sovrascrivere il metodo magico __eq__ e utilizzo super per accedere al metodo di base trovato in object, viene visualizzato un errore. Non c'è modo questo è un bug, ma ci si sente sicuro come uno:L'oggetto 'super' non ha attributo '__eq__'

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

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

Questo è poco intuitivo, perché object.__eq__ esiste, ma per class A(object): pass non è così. Se non mi sbaglio resort __eq__ a un controllo is, in modo che possa essere la soluzione qui, ma utilizzando is anziché super non è mixin friendly. Andare su quella strada è ok nel mio caso, ma in altri potrebbe non esserlo.

Qualsiasi suggerimento o informazioni sul motivo per cui lo __eq__ funziona in questo modo sarebbe fantastico.

+1

L'errore viene generato in 2.7 ma non generato in 3.5 –

+1

No, 'object' non supporta' __eq__' in ** istanze ** ... prova 'oggetto() .__ eq__', genererà un' AttributeError '... invece' object .__ eq__ è (probabilmente) un metodo di classe per verificare se i tipi sono identici (ad es. 'oggetto .__ eq __ (oggetto)') – donkopotamus

+0

@donkopotamus: Questo non confronta il tuo oggetto con 'altro'; confronterà un oggetto "vuoto" appena creato con "altro". – BrenBarn

risposta

4

Come osservato in risposta di Will, object() in realtà non implementare __eq__ a tutti per le istanze (in python 2.7).

Stai per essere ingannati dal fatto che object.__eq__ esiste a credere che deve essere un metodo che controlla se casi dell'oggetto sono uguali

Invece, object.__eq__ è in realtà un metodo di classe, ereditato da type, cioè usato per verificare se i tipi sono uguali.

Cioè, per gestire espressioni come object == int e object == object.

2

Questo perché object() non implementa effettivamente uno __eq__(). Il "default" qui sarebbe:

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

     return self == other 

Ma, se quello che si sta tentando aveva funzionato, si sarebbe in realtà essere il controllo se l'istanza self della classe genitore eguagliato other. E, è lo stesso oggetto (self), così sarebbe. Così l'equivalente più del vostro codice sarebbe in realtà:

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

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

Come ho commentato una risposta cancellata in precedenza, il tuo secondo esempio non eredita il comportamento predefinito, poiché se si esegue 'x = A()', quindi 'x == x' restituisce False. (Il tuo primo esempio causa una ricorsione infinita.) – BrenBarn

+0

Grazie, questo dovrebbe essere corretto nella mia modifica. – Will

Problemi correlati