0

According to the Python Language Reference:

The ‘is’ operator compares the identity of two objects; the id() function returns an integer representing its identity.

CPython implementation detail: For CPython, id(x) is the memory address where x is stored.

However:

>>> object() is object()
False
>>> id(object()) == id(object())
True

How is this consistent with the documented behavior? Why are the two objects considered non-identical although their id() are the same? Why is object() is object() considered False although id(object()) == id(object()) is True?

Flux
  • 9,805
  • 5
  • 46
  • 92
  • Because here, the lifetime of your objects *do not overlap*, even though they are used in the same expression. You can think of what's going on here like this, 1) create an `object()`, pass it to `id()`, the `id` function returns, and the object created is *no longer referenced* so it is free to be garbage collected, 2) then create *another object*, pass *that* object to `id`. Since this new object doesn't exist during the lifetime of the original object, the runtime is happy and free to re-use the address and it does, 3)now compare the two resulting numbers for equality – juanpa.arrivillaga Mar 12 '22 at 00:57
  • Instead, though, `a = object(); b = object(); print(id(a) == id(b))` will always be false, because in this case, both objects *have overlapping lifetimes* since you are keeping a reference around. See the linked duplicates – juanpa.arrivillaga Mar 12 '22 at 00:58
  • @juanpa.arrivillaga Do you know whether it's somehow documented/guaranteed somewhere that the two objects in `object() is object()` have overlapping lifetimes? I think theoretically Python could handle that basically the same way as the version with `id`, i.e., it could create the first object, then `is` would fetch its id, then the first object could get discarded, the second created and `is` would fetch its id and possibly see the same. Is that ruled out by something? – Kelly Bundy Mar 12 '22 at 01:14
  • @KellyBundy Interesting question. At the language-reference level? No, not anything that comes to mind immediately. EDIT: I would hope to find something [here](https://docs.python.org/3/reference/expressions.html#is-not) but that's pretty sparse. Note, for [boolean operator expression](https://docs.python.org/3/reference/expressions.html#boolean-operations) it does carefully define when things get evaluated. – juanpa.arrivillaga Mar 12 '22 at 01:21
  • @juanpa.arrivillaga Yeah, nothing except that section comes to mind for me, either. For context: This originated at the OP's [previous question](https://stackoverflow.com/q/71404046/12671057) where they said that `object() is object()` is guaranteed to be `False` and everybody apparently just accepted that except some troublemaker (me :-). You're right, boolean operators define what happens. And the two objects in `object() and object()` can have the same id. And in a sense, `and` is pretty similar to `is` (it's an operator controlled by Python, not by magic methods of the objects). – Kelly Bundy Mar 12 '22 at 01:52

0 Answers0