[Résolu ]Opérateur de comparaison en python

Opérateur de comparaison en python [Résolu ] - Python - Programmation

Marsh Posté le 19-02-2008 à 14:05:42    

Bonjour
 
D'après le livre de gérard swinen l'opérateur de comparaison == regarde si les deux variables pointent sur le même objet.
Par exemple:

Code :
  1. >>> class test:
  2. ...     def __init__(self):
  3. ...             self.a=0
  4. ...
  5. >>> x=test()
  6. >>> y=test()
  7. >>> x==y
  8. False


 
J'aimerai savoir comment est ce que l'on compare la valeur de deux objets.
En gros je recherche l'équivalent de la méthode equals() en java.
 
Merci d'avance de votre aide :D.

Message cité 1 fois
Message édité par Anonymouse le 05-04-2008 à 00:00:13
Reply

Marsh Posté le 19-02-2008 à 14:05:42   

Reply

Marsh Posté le 19-02-2008 à 14:21:04    

Anonymouse a écrit :

Bonjour

 

D'après le livre de gérard swinen l'opérateur de comparaison == regarde si les deux variables pointent sur le même objet.
Par exemple:

Code :
  1. >>> class test:
  2. ...     def __init__(self):
  3. ...             self.a=0
  4. ...
  5. >>> x=test()
  6. >>> y=test()
  7. >>> x==y
  8. False
 

J'aimerai savoir comment est ce que l'on compare la valeur de deux objets.
En gros je recherche l'équivalent de la méthode equals() en java.

 

Merci d'avance de votre aide :D.

 



Python a tout un jeu de "méthodes magiques" qui fournissent des hooks pour ce genre de trucs.

 

Tu peux les trouver dans la doc, reference > Data Model > Special Method Names

 

Pour l'égalité, tu veux soit __eq__

Code :
  1. >>> class Test(object):
  2.     def __init__(self, value):
  3.         self.v = value
  4.     def __eq__(self, other):
  5.         return self.v == other.v
  6.  
  7.     
  8. >>> x = Test(0)
  9. >>> y = Test(0)
  10. >>> x == y
  11. True
  12. >>> x is y
  13. False
  14. >>>


soit __cmp__

Code :
  1. >>> class Test(object):
  2.     def __init__(self, value):
  3.         self.v = value
  4.     def __cmp__(self, other):
  5.         return cmp(self.v, other.v)
  6.  
  7.     
  8. >>> x = Test(0)
  9. >>> y = Test(0)
  10. >>> x == y
  11. True
  12. >>> x is y
  13. False
  14. >>>
 

note: en Python, "==" teste l'égalité, pas l'idéntité (testée avec l'opérateur "is" ). C'est juste que par défaut Python définit l'égalité comme étant l'identité s'il n'a pas plus d'infos

Message cité 1 fois
Message édité par masklinn le 19-02-2008 à 14:23:29

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 19-02-2008 à 14:38:00    

masklinn a écrit :


Python a tout un jeu de "méthodes magiques" qui fournissent des hooks pour ce genre de trucs.
 
Tu peux les trouver dans la doc, reference > Data Model > Special Method Names
 
Pour l'égalité, tu veux soit __eq__

Code :
  1. >>> class Test(object):
  2.     def __init__(self, value):
  3.         self.v = value
  4.     def __eq__(self, other):
  5.         return self.v == other.v
  6.  
  7.     
  8. >>> x = Test(0)
  9. >>> y = Test(0)
  10. >>> x == y
  11. True
  12. >>> x is y
  13. False
  14. >>>


soit __cmp__

Code :
  1. >>> class Test(object):
  2.     def __init__(self, value):
  3.         self.v = value
  4.     def __cmp__(self, other):
  5.         return cmp(self.v, other.v)
  6.  
  7.     
  8. >>> x = Test(0)
  9. >>> y = Test(0)
  10. >>> x == y
  11. True
  12. >>> x is y
  13. False
  14. >>>


 
note: en Python, "==" teste l'égalité, pas l'idéntité (testée avec l'opérateur "is" ). C'est juste que par défaut Python définit l'égalité comme étant l'identité s'il n'a pas plus d'infos


 
Merci beaucoup voila une info super utile que je ne trouvais pas ailleurs  :hello:  :hello: .
 
Sinon tant que tu est la faut-il privilégier une des deux méthodes? Ou il n'y a aucune différence?
 
 
 


Message édité par Anonymouse le 19-02-2008 à 14:42:38
Reply

Marsh Posté le 19-02-2008 à 14:50:14    

Dans ton cas, si tu as juste besoin de l'égalité donc j'aurais tendance à juste implémenter __eq__, pas besoin de s'embêter avec __cmp__ (autrement plus complexe)


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 19-02-2008 à 15:03:03    

Au fait est-ce que tu saurai si lorsque je crée deux objets identiques la référence aux deux objets ne sera pas la même?
Car en java la machine virtuelle optimise la chose ne créant qu'un objet pour deux variables identique.
 
Or je travaille sur un programme qui va me créer des objets pointant sur d'autres qui eux même pointent sur d'autre objets qui repointent sur les premiers.
Ca va me créer en une sorte de graphe très complexe (Un MCD représenté en objet).
 
Donc créer une méthode __eq__() sur des objets de se type est très complexe (Il faut grosso modo comparer deux graphes).
La plupart du temps je n'ai besoin de savoir que si deux variables pointent sur le même objet. Il ne faudrait pas que l'opérateur "is" soit mis en défaut par la machine virtuelle.  :bounce:

Message cité 2 fois
Message édité par Anonymouse le 20-02-2008 à 23:13:20
Reply

Marsh Posté le 24-02-2008 à 22:36:57    

Anonymouse a écrit :

Au fait est-ce que tu saurai si lorsque je crée deux objets identiques la référence aux deux objets ne sera pas la même?
Car en java la machine virtuelle optimise la chose ne créant qu'un objet pour deux variables identique.
 
Or je travaille sur un programme qui va me créer des objets pointant sur d'autres qui eux même pointent sur d'autre objets qui repointent sur les premiers.
Ca va me créer en une sorte de graphe très complexe (Un MCD représenté en objet).
 
Donc créer une méthode __eq__() sur des objets de se type est très complexe (Il faut grosso modo comparer deux graphes).
La plupart du temps je n'ai besoin de savoir que si deux variables pointent sur le même objet. Il ne faudrait pas que l'opérateur "is" soit mis en défaut par la machine virtuelle.  :bounce:


Non. Si tu crées deux objets identiques, tu obtiens en Python deux instances différentes dans deux variables distinctes. Tu peux d'ailleurs le vérifier en allant modifier un des deux objets.
Maintenant, je présume que ton objet contient lui-même des objets plus simple. Ben faut que tu implémentes une méthode "eq" sur chaque objet simple. Puis tu implémentera la méthode "eq" de l'objet complexe en comparant chaque objet simple.
Exemple => un programme qui crée deux rectangles et qui les compare

Code :
  1. #!/usr/bin/env python
  2. # coding: Latin-1 -*-
  3.  
  4. class cPoint:
  5.     "Point mathématique"
  6.  
  7.     def __init__(self, x=0, y=0):
  8.         self.x=x;
  9.         self.y=y;
  10.     def __eq__ (self, other):
  11.         return self.x == other.x and self.y == other.y
  12.  
  13. class cRectangle:
  14.     "Rectangle"
  15.     def __init__(self, l, L):
  16.         self.l=l
  17.         self.L=L
  18.         self.coin=[]
  19.         self.coin.append(cPoint(0, 0))
  20.         self.coin.append(cPoint(0, L))
  21.         self.coin.append(cPoint(l, L))
  22.         self.coin.append(cPoint(l, 0))
  23.  
  24.     def __eq__(self, other):
  25.         for i in range(4):
  26.             if not self.coin[i] == other.coin[i]: return False
  27.         return True
  28.  
  29. a=cRectangle(20, 10)
  30. b=cRectangle(20, 10)
  31. print a == b


 
Petite remarque => j'ai été obligé d'utiliser "not ==" car je n'avais pas redéfini l'opérateur "!=" pour la classe cPoint...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 24-02-2008 à 23:11:57    

Anonymouse a écrit :

Au fait est-ce que tu saurai si lorsque je crée deux objets identiques la référence aux deux objets ne sera pas la même?
Car en java la machine virtuelle optimise la chose ne créant qu'un objet pour deux variables identique.


Je sais pas où t'as vu jouer ça, mais c'est n'importe quoi.
 
Même pour les chaînes de caractères, c'est pas nécessairement le cas, alors avec les objets userland... [:pingouino]

Anonymouse a écrit :

Donc créer une méthode __eq__() sur des objets de se type est très complexe (Il faut grosso modo comparer deux graphes).
La plupart du temps je n'ai besoin de savoir que si deux variables pointent sur le même objet. Il ne faudrait pas que l'opérateur "is" soit mis en défaut par la machine virtuelle.  :bounce:


Faut implementer __eq__ récursivement [:spamafote]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 04-04-2008 à 23:59:32    

masklinn a écrit :


Je sais pas où t'as vu jouer ça, mais c'est n'importe quoi.
 
Même pour les chaînes de caractères, c'est pas nécessairement le cas, alors avec les objets userland... [:pingouino]


 

masklinn a écrit :


Faut implementer __eq__ récursivement [:spamafote]


 
Ok merci :d

Reply

Marsh Posté le 05-04-2008 à 20:38:37    

masklinn a écrit :


Faut implementer __eq__ récursivement [:spamafote]


"récursivement" n'est pas vraiment le terme adéquat. Faut implémenter un "__eq__" qui va comparer chaque sous-objet, charge au programmeur du sous-objet d'implémenter son propre "__eq__"...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 06-04-2008 à 10:04:22    

Sve@r a écrit :


"récursivement" n'est pas vraiment le terme adéquat. Faut implémenter un "__eq__" qui va comparer chaque sous-objet, charge au programmeur du sous-objet d'implémenter son propre "__eq__"...


 
Ouais sauf que quand t'as un objet "object1" qui à un sous-objet "object2" qui a un sous-objet "object3" qui, lui même, à un sous objet "object1".
Bah ça boucle.

Reply

Marsh Posté le 06-04-2008 à 10:04:22   

Reply

Marsh Posté le 07-04-2008 à 10:12:58    

Anonymouse a écrit :


 
Ouais sauf que quand t'as un objet "object1" qui à un sous-objet "object2" qui a un sous-objet "object3" qui, lui même, à un sous objet "object1".
Bah ça boucle.


En effet, c'est une sale boucle. Mais on en est à comparer deux objets de type "object1". Donc comment envisagerais-tu de comparer deux objets "object1" définis comme ci-dessus ?
Si t'arrives pas à envisager cette comparaison avec des mots (des dessins, des schémas) tu pourras jamais le programmer en Python.  Et si tu trouves un raisonnement qui te permette de comparer ces deux objets, alors tu pourras adapter ce raisonnement à Python.
 
Quoi qu'il en soit, un objet tel que décrit ci-dessus est très difficile à traiter quel que soit le traitement que tu voudras y faire... mais la base de la comparaison sera quand-même d'implémenter un "__eq__" sur chaque objectX. Charge à toi de t'arranger pour que le "__eq__" s'arrête quand il faut.


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed