Peter Wood Peter Wood - 3 months ago 12
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

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:


which doesn't tell me whether anything is done before calling


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
>>> ue == ue

so __eq__ must be called before id, but:

>>> class NoEqual(object):

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

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.