Quel est le meilleur moyen de comparer deux instances d'un objet pour l'égalité dans Python? J'aimerais pouvoir faire quelque chose comme
Exemple:
doc1 = ErrorDocument(path='/folder',title='Page')
doc2 = ErrorDocument(path='/folder',title='Page')
if doc1 == doc2: # this should be True
#do something
MODIFIER:
Pour clarifier davantage la question. J'aimerais comparer les valeurs d'attributs et créer une solution plus générique que
def __eq__(self, other):
return self.path == other.path and self.title == other.title
La méthode __eq__()
devrait-elle ressembler à ceci?
def __eq__(self, other):
# Is the other instance of the same object
# Loop through __dict__ and compare values to attributes of other
Comme d'habitude avec Python, c'est KISS :
class Test(object):
def __init__(self, attr1, attr2):
self.attr1 = attr1
self.attr2 = attr2
def __str__(self):
return str(self.__dict__)
def __eq__(self, other):
return self.__dict__ == other.__dict__
t1 = Test("foo", 42)
t2 = Test("foo", 42)
t3 = Test("bar", 42)
print t1, t2, t3
print t1 == t2
print t2 == t3
Il produit:
{'attr2': 42, 'attr1': 'foo'} {'attr2': 42, 'attr1': 'foo'} {'attr2': 42, 'attr1': 'bar'}
True
False
NB: sachez qu'avant Python 3.0, vous utiliseriez plutôt __cmp__
au lieu de __eq__
, en procédant de la même manière.
Vous remplacez les opérateurs de comparaison riches dans votre objet.
class MyClass:
def __lt__(self, other):
# return comparison
def __le__(self, other):
# return comparison
def __eq__(self, other):
# return comparison
def __ne__(self, other):
# return comparison
def __gt__(self, other):
# return comparison
def __ge__(self, other):
# return comparison
Comme ça:
def __eq__(self, other):
return self._id == other._id
Implémentez la méthode __eq__
dans votre classe; quelque chose comme ça:
def __eq__(self, other):
return self.path == other.path and self.title == other.title
Éditer: si vous voulez que vos objets se comparent égaux si et seulement s'ils ont des dictionnaires d'instance égaux:
def __eq__(self, other):
return self.__dict__ == other.__dict__
En résumé:
__eq__
plutôt que __cmp__
, sauf si vous exécutez python <= 2.0 (__eq__
a été ajouté dans 2.1)__ne__
(devrait être quelque chose comme return not self.__eq__(other)
ou return not self == other
sauf cas très spécial)Si vous souhaitez comparer avec un objet pouvant être Aucun, vous devez l'implémenter. L'interprète ne peut pas le deviner ... (voir exemple ci-dessous)
class B(object):
def __init__(self):
self.name = "toto"
def __eq__(self, other):
if other is None:
return False
return self.name == other.name
class A(object):
def __init__(self):
self.toto = "titi"
self.b_inst = B()
def __eq__(self, other):
if other is None:
return False
return (self.toto, self.b_inst) == (other.toto, other.b_inst)
Lors de la comparaison d'instances d'objets, la fonction __cmp__
est appelée.
Si l'opérateur == ne fonctionne pas pour vous par défaut, vous pouvez toujours redéfinir la fonction __cmp__
pour l'objet.
Modifier:
Comme il a été souligné, la fonction __cmp__
est obsolète depuis la version 3.0 . Vous devez plutôt utiliser les méthodes “comparaison riche” .
Si vous souhaitez obtenir une comparaison attribut par attribut et voir si et où il échoue, vous pouvez utiliser la compréhension de la liste suivante:
[i for i,j in
Zip([getattr(committed_vans_events[0][0].request, attr)
for attr in dir(committed_vans_events[0][0].request)],
[getattr(self.vans_states[0].onboard_passengers[0], attr)
for attr in dir(self.vans_states[0].onboard_passengers[0])])
if not i==j]
L'avantage supplémentaire est que vous pouvez y insérer une ligne et entrer dans la fenêtre "Evaluer Expression" lors du débogage dans PyCharm.