Are objects with the same id always equal when comparing them with ==? Are objects with the same id always equal when comparing them with ==? python python

Are objects with the same id always equal when comparing them with ==?


Not always:

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

or formulated the same way as in the question:

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

but

>>> nan == nanFalse

NaN is a strange thing. Per definition it is not equal nor less or greater than itself. But it is the same object. More details why all comparisons have to return False in this SO question.


The paper is right. Consider the following.

class WeirdEquals:    def __eq__(self, other):        return Falsew = WeirdEquals()print("id(w) == id(w)", id(w) == id(w))print("w == w", w == w)

Output is this:

id(w) == id(w) Truew == w False


id(o1) == id(o2) does not imply o1 == o2.

Let's have a look at this Troll which overrides __eq__ to always return False.

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

That being said, there should be very few examples in the standard library where the object-ids match but __eq__ can return False anyway, kudos @MarkMüller for finding a good example.

So either the objects are insane, very special (like nan), or concurrency bites you. Consider this extreme example, where Foo has a more reasonable __eq__ method (which 'forgets' to check the ids) and f is f is always True.

import threadingclass Foo(object):    def __init__(self):        self.x = 1    def __eq__(self, other):        return isinstance(other, Foo) and self.x == other.xf = Foo()class MutateThread(threading.Thread):    def run(self):        while True:            f.x = 2            f.x = 1class CheckThread(threading.Thread):    def run(self):        i = 1        while True:            if not (f == f):                print 'loop {0}: f != f'.format(i)             i += 1MutateThread().start()CheckThread().start()

Output:

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