Inverse of id()?
Duncan Booth
duncan.booth at invalid.invalid
Mon May 21 04:10:15 EDT 2007
"Ian Clark" <turbana at gmail.com> wrote:
> Now I tried this in the shell and got different id's for a and b, but
> when I typed it into a file and ran from there the id's where always
> the same. Must have something to do with other programs allocating
> space faster than I can type everything out (I do have a few processes
> going). Interesting.
>
No, what other processes are doing isn't going to affect the memory
allocation within your Python process. More likely the interactive
interpreter is allocating or releasing other objects when it compiles
each line of input which stops you seeing the duplicated id. You can get
it to reuse the id by making sure you force everything to be compiled in
one go:
>>> class A: pass
>>> class B: pass
>>> a = A();print id(a);del a;b = B();print id(b)
12948384
12948384
>>> if 1:
a = A()
print id(a)
del a
b = B()
print id(b)
12948464
12948464
>>>
Gabriel's point however is not that this particular sequence will always
result in duplicate ids (it is just an artifact of the implementation
and could change), but that ids in general are re-used so any mapping
from id->object is ambiguous unless you can be certain that the object
whose id you took is still alive.
There are two common ways to do the reverse mapping: either store the
ids and objects in a dict thereby forcing the objects to continue to
exist, or store them in a weakref.WeakValueDictionary and be very
careful not to access an expired (and possibly reused) id.
For a completely safe technique which works with any weakly
referenceable object just ignore Python's id function and write your own
which never reuses an id. Then you can safely map from your own id
values back to the object if it still exists or get an exception if it
doesn't:
>>> lastid = 0
>>> idmap = weakref.WeakValueDictionary()
>>> def myid(o):
global lastid
lastid += 1
idmap[lastid] = o
return lastid
>>> def getfrommyid(id):
return idmap[id]
>>> a = A()
>>> print myid(a)
1
>>> del a
>>> b = B()
>>> print myid(b)
2
>>> print getfrommyid(2)
<__main__.B instance at 0x00CD43F0>
>>> print getfrommyid(1)
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
print getfrommyid(1)
File "<pyshell#25>", line 2, in getfrommyid
return idmap[id]
File "C:\Python25\Lib\weakref.py", line 54, in __getitem__
o = self.data[key]()
KeyError: 1
>>>
Unfortunately that won't help with the common builtin objects as they
aren't weakly referenceable.
More information about the Python-list
mailing list