Peter Wood Peter Wood - 24 days ago 5
Python Question

Does comparing using `==` compare identities before comparing values?

If I compare two variables using

==
, does Python compare the identities, and, if they're not the same, then compare the values?

For example, I have two strings which point to the same string object:

>>> a = 'a sequence of chars'
>>> b = a


Does this compare the values, or just the ids?:

>>> b == a
True


It would make sense to compare identity first, and I guess that is the case, but I haven't yet found anything in the documentation to support this. The closest I've got is this:


x==y
calls
x.__eq__(y)



which doesn't tell me whether anything is done before calling
x.__eq__(y)
.

Answer

For user-defined class instances, is is used as a fallback - where the default __eq__ isn't overridden, a == b is evaluated as a is b. This ensures that the comparison will always have a result (except in the NotImplemented case, where comparison is explicitly forbidden).

This is (somewhat obliquely - good spot Sven Marnach) referred to in the data model documentation (emphasis mine):

User-defined classes have __eq__() and __hash__() methods by default; with them, all objects compare unequal (except with themselves) and x.__hash__() returns an appropriate value such that x == y implies both that x is y and hash(x) == hash(y).


You can demonstrate it as follows:

>>> class Unequal(object):
    def __eq__(self, other):
        return False


>>> ue = Unequal()
>>> ue is ue
True
>>> ue == ue
False

so __eq__ must be called before id, but:

>>> class NoEqual(object):
    pass

>>> ne = NoEqual()
>>> ne is ne
True
>>> ne == ne
True

so id must be invoked where __eq__ isn't defined.


You can see this in the CPython implementation, which notes:

/* If neither object implements it, provide a sensible default
   for == and !=, but raise an exception for ordering. */

The "sensible default" implemented is a C-level equality comparison of the pointers v and w, which will return whether or not they point to the same object.