If I compare two variables using
>>> a = 'a sequence of chars'
>>> b = a
>>> b == a
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).
User-defined classes have
__hash__()methods by default; with them, all objects compare unequal (except with themselves) and
x.__hash__()returns an appropriate value such that
x == yimplies both that
x is yand
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
__eq__ must be called before
>>> class NoEqual(object): pass >>> ne = NoEqual() >>> ne is ne True >>> ne == ne True
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
w, which will return whether or not they point to the same object.