2016-05-23 2 views
11

Lorsque j'essaie de remplacer la méthode magique __eq__, et d'utiliser super pour accéder à la méthode de base trouvée dans object, j'obtiens une erreur. Il n'y a aucun moyen c'est un bug, mais il se sent comme une vedette:'super' objet n'a pas d'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__' 

Ceci est unintuitive parce object.__eq__ existe, mais pour class A(object): pass il ne fonctionne pas. Si je ne me trompe pas __eq__ stations à un contrôle is, de sorte que peut-être la solution de contournement, mais en utilisant is au lieu de super n'est pas MIXIN amical. Aller dans cette voie est correct dans mon cas, mais dans d'autres, ce n'est peut-être pas le cas.

Toute suggestion ou information sur les raisons __eq__ fonctionne de cette façon serait génial.

+1

L'erreur est survenue en 2.7 mais pas en 3.5 –

+1

Non, 'object' ne supporte pas' __eq__' sur ** instances ** ... essaie 'object() .__ eq__', cela soulèvera un' AttributeError '... au lieu de' object .__ eq__ est (probablement) un classmethod pour vérifier si les types sont identiques (par exemple 'object .__ eq __ (object)') – donkopotamus

+0

@donkopotamus: Cela ne comparera pas votre objet avec 'other'; il va comparer un objet "vide" nouvellement créé avec 'other'. – BrenBarn

Répondre

4

Comme indiqué dans la réponse de Will, object() ne met pas en fait __eq__ du tout pour les instances (en python 2.7).

Vous êtes trompé par le fait que object.__eq__ existe en leur faisant croire qu'il doit être une méthode qui vérifie si instances d'objet sont égaux

Au lieu de cela, object.__eq__ est en fait une méthode de classe, héritée de type, qui est utilisé pour vérifier si les types sont égaux.

En d'autres termes, pour gérer des expressions telles que object == int et object == object.

2

C'est parce que object() ne met pas en fait un __eq__(). Le « défaut » serait ici:

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

     return self == other 

Mais, si ce que vous essayez aviez travaillé, vous fait vérifierez si l'instance self de la classe parente égalée other. Et, c'est le même objet (self), il en serait ainsi. Donc, le plus proche équivalent de votre code serait en fait:

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

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

Comme je l'ai commenté une réponse précédemment supprimé, votre deuxième exemple n'hérite pas du comportement par défaut, puisque si vous faites 'x = A()', alors 'x == x' renvoie False. (Votre premier exemple provoque une récursion infinie.) – BrenBarn

+0

Merci, cela devrait être corrigé dans mon édition. – Will