7
votes

Python: cas où x == y et x .__ EQ__Y () renvoie différentes choses. Pourquoi?

Je prends mon premier cours de sciences informatiques et je viens d'apprendre à la mise en œuvre de la classe et à l'héritage. En particulier, nous venons de couvrir la méthode de remplacement et de la manière dont nous définissons les classes hériter de la superclasse par défaut. En tant que l'un de mes exemples, essayez ce cas particulier d'héritage, j'ai utilisé le code suivant: xxx

Je m'attendais au résultat de (x == y) , car Comme je le comprends, la valeur par défaut pour __ eq __ () est de vérifier si ce sont les mêmes objets ou non, ne vous inquiétez pas du contenu. Qui est false , x et y avoir le même contenu mais sont des objets différents. Le second m'a surpris cependant.

Alors mes questions: je pensais (x == y) et x. __ eq __ (y) était synonyme et fait exactement le même appel. Pourquoi celles-ci produisent-elles une sortie différente? Et pourquoi le deuxième retour conditionnel notimplementé ?


0 commentaires

3 Réponses :


0
votes

Si vous avez implémenté la fonction __ __ __ __ __ () fonction pour une classe, elle est appelée lorsque vous utilisez x == y . Sinon x == y s'appuie sur une logique de comparaison par défaut. __ eq __ () n'est pas mis en œuvre automatiquement lorsque vous définissez une classe.


1 commentaires

En fait (si vous utilisez Python 3, ou des classes de style neuf dans Python 2), est un __ eq __ __ que vous obtenez gratuitement - celui que vous héritez de < Code> Object . Avec des classes de style ancien, si vous ne définissez pas __ eq __ , vous n'obtirez jamais notimplementé de celui-ci comme dans la question - vous obtiendrez un attributError.



9
votes

L'opérateur == est équivalent à la fonction eq , qui appellera à l'intérieur de l'intérieur le __ eq __ méthode de l'opérande gauche s'il existe Essayez de déterminer l'égalité. Ce n'est pas le seul chose que cela va faire, et si __ eq __ n'existe pas, comme c'est le cas ici, il effectuera d'autres chèques, tels que la vérification de la vérification si les deux sont les deux. le même objet, ou __ cmP __ pré-python 3.

Donc, en un mot, votre confusion découle de cette hypothèse, ce qui est incorrect:

Je pensais (x == y) et x .__ eq __ (y) étaient synonymes et ont fait exactement le même appel

En fait, (x == y) et opérateurs.eq (x, y) est synonyme, et x .__ eq __ (y) est l'une des choses eq (x, y) va essayer de vérifier.


0 commentaires

6
votes

Le notaimplemented valeur Vous voyez renvoyé de votre hérité __ eq __ est une valeur intégrée spéciale utilisée comme sentinelle à Python. Il peut être renvoyé par __ magique __ Méthodes qui implémentent des opérateurs de mathématiques ou de comparaison pour indiquer que la classe ne prend pas en charge l'opérateur qui a été tenté (avec les arguments fournis).

Ceci peut être plus utile que de soulever une exception, car il permet à Python de revenir à d'autres options pour résoudre l'utilisation de l'opérateur. Par exemple, si vous faites x + y , Python essaiera d'abord d'exécuter x .__ ajouter __ (y) . Si cela retourne notimplementé , essayez la version "Reverse", y .__ radd __ (x) , qui peut fonctionner si y est un type plus sophistiqué que x est.

Dans le cas, vous vous demandez, x == y , Python essaie d'abord x .__ eq __ (y) , puis y .__ eq __ (x ) , et enfin x est Y (qui sera toujours évalué à une valeur booléenne). Étant donné que objet .__ eq __ renvoie notamplemented Dans tous les cas, votre classe redevient à la comparaison d'identité lorsque vous utilisez l'opérateur réel, mais vous indique le notamplemented Sentinel lorsque vous appelez __ eq __ directement.


0 commentaires