59 votes

Les objets ayant le même identifiant sont-ils toujours égaux lorsqu'on les compare avec == ?

Si j'ai deux objets o1 et o2, et que l'on sait que

id(o1) == id(o2)

renvoie à vrai .

Alors, s'ensuit-il que

o1 == o2

Ou n'est-ce pas toujours le cas ? L'article sur lequel je travaille dit que ce n'est pas le cas, mais à mon avis, cela devrait être vrai !

129voto

Mike Müller Points 2963

Pas toujours :

>>> nan = float('nan')
>>> nan is nan
True

ou formulé de la même manière que dans la question :

>>> id(nan) == id(nan)
True

mais

>>> nan == nan
False

NaN est une chose étrange. Par définition, elle n'est ni égale, ni inférieure, ni supérieure à elle-même. Mais c'est le même objet. Plus de détails sur la raison pour laquelle toutes les comparaisons doivent retourner False en cette question SO .

58voto

recursive Points 34729

Le journal a raison. Considérez ce qui suit.

class WeirdEquals:
    def __eq__(self, other):
        return False

w = WeirdEquals()
print("id(w) == id(w)", id(w) == id(w))
print("w == w", w == w)

Le résultat est le suivant :

id(w) == id(w) True
w == w False

25voto

timgeb Points 5966

id(o1) == id(o2) n'implique pas o1 == o2 .

Jetons un coup d'œil à ceci Troll qui prévaut sur __eq__ de toujours revenir False .

>>> class Troll(object):
...     def __eq__(self, other):
...         return False
... 
>>> a = Troll()
>>> b = a
>>> id(a) == id(b)
True
>>> a == b
False

Ceci étant dit, il devrait y avoir muy quelques exemples dans la bibliothèque standard où les identifiants d'objets correspondent mais __eq__ peut retourner False Quoi qu'il en soit, félicitations à @MarkMüller pour avoir trouvé un bon exemple.

Donc soit les objets sont fous, très spéciaux (comme nan), soit la concurrence vous mord. Considérez cet exemple extrême, où Foo est plus raisonnable __eq__ (qui " oublie " de vérifier les identifiants) et la méthode f is f est toujours True .

import threading

class Foo(object):
    def __init__(self):
        self.x = 1

    def __eq__(self, other):
        return isinstance(other, Foo) and self.x == other.x

f = Foo()

class MutateThread(threading.Thread):
    def run(self):
        while True:
            f.x = 2
            f.x = 1

class CheckThread(threading.Thread):
    def run(self):
        i = 1
        while True:
            if not (f == f):
                print 'loop {0}: f != f'.format(i) 
            i += 1

MutateThread().start()
CheckThread().start()

Sortie :

$ python eqtest.py
loop 520617: f != f
loop 1556675: f != f
loop 1714709: f != f
loop 2436222: f != f
loop 3210760: f != f
loop 3772996: f != f
loop 5610559: f != f
loop 6065230: f != f
loop 6287500: f != f
...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X