How much can I rely on the object's id()
and its uniqueness in practice? E.g.:
- Does
id(a) == id(b)
meana is b
or vice versa? What about the opposite? - How safe is it to save an
id
somewhere to be used later (e.g. into some registry instead of the object itself)?
(Written as a proposed canonical in response to Canonicals for Python: are objects with the same id() the same object, `is` operator, unbound method objects)
According to the
id()
documentation, anid
is only guaranteed to be uniqueAs such, comparing
id
s is not safe unless you also somehow ensure that both objects whoseid
s are taken are still alive at the time of comparison (and are associated with the same Python interpreter instance, but you need to really try to make that become false).Which is exactly what
is
does -- which makes comparingid
s redundant. If you cannot use theis
syntax for whatever reason, there's alwaysoperator.is_
.Now, whether an object is still alive at the time of comparison is not always obvious (and sometimes is grossly non-obvious):
Accessing some attributes (e.g. bound methods of an object) creates a new object each time. So, the result's
id
may or may not be the same on each attribute access.Example:
If an object is created as a result of calculating an expression and not saved anywhere, it's immediately discarded,1 and any object created after that can take up its
id
.This is even true within the same code line. E.g. the result of
id(create_foo()) == id(create_bar())
is undefined.Example:
Due to the above safety requirements when comparing
id
s, saving anid
instead of the object is not very useful because you have to save a reference to the object itself anyway -- to ensure that it stays alive. Neither is there any performance gain:is
implementation is as simple as comparing pointers.Finally, as an internal optimization (and implementation detail, so this may differ between implementations and releases), CPython reuses some often-used simple objects of immutable types. As of this writing, that includes small integers and some strings. So even if you got them from different places, their
id
s might coincide.This does not (technically) violate the above
id()
documentation's uniqueness promises: the reused object stays alive through all the reuses.This is also not a big deal because whether two variables point to the same object or not is only practical to know if the object is mutable: if two variables point to the same mutable object, mutating one will (unexpectedly) change the other, too. Immutable types don't have that problem, so for them, it doesn't matter if two variables point to two identical objects or to the same one.
1Sometimes, this is called "unnamed expression".