As I wrote elsewhere:
id
is only defined as a number unique to the element among currently existing elements. Some Python implementations (in fact, all main ones but CPython) do not return the memory address.
%~> pypy
Python 2.7.3 (480845e6b1dd219d0944e30f62b01da378437c6c, Aug 08 2013, 17:02:19)
[PyPy 2.1.0 with GCC 4.8.1 20130725 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
And now for something completely different: ``arguably, everything is a niche''
>>>> a = 1
>>>> b = 2
>>>> c = 3
>>>> id(a)
9L
>>>> id(b)
17L
>>>> id(c)
25L
So you have to guarantee that it is the memory address. Furthermore, because of this Python provides no id → object
mapping, especially as the object that an id
maps to can be changed if the original is deleted.
You have to ask why you're holding the id
. If it's for space reasons, bear in mind that containers actually hold references to items, so [a, a, a, a, a]
actually takes less space than [id(a), id(a), id(a), id(a), id(a)]; a
.
You can consider also making a dict
of {id: val}
for all the relevant items and storing that. This will keep val
alive, so you can use weakref
s to allow the val
s to be garbage collected. Remember, use weakref
if you want a weakref
.
So basically it's because there's no reliable solution that's platform-independant.
it bothers me that we have an object and something that would give its address
Then just remember that we do not. CPython only optimises id
under the (correct) assumption that the address is unique. You should never treat is as an address because it's not defined to be.
Why was this decision made?
Because if we were to access things from their id
we'd be able to do all sorts of stupid stuff like accessing uninitialised stuff. It also prevents interpreters from optimising things by moving addresses around (JIT compilers like PyPy could not exist as easily if items had to have memory addresses). Furthermore, there is no guarantee that the item is either alive or even the same item at any point.
When references take less space than an integer (which is a reference + an numeric object) there is no point just not using a reference(or a weakref
if preferred), which will always do the right thing.