Python: di
Friday, August 24th, 2007The id() function doesn’t have an inverse1. Now it does.
>>> k = object() >>> print k <object object at 0x9a3b8> >>> id(k) 631736 >>> from di import di >>> j = di(631736) >>> j <object object at 0x9a3b8> >>> id(j) 631736
Stupid simple module available in my SVN repository.
1 For good reason. An object’s id() is just its address in memory. This hack is effectively exposing a pointer — a fragile, prone to disappear out from under you, nasty, C-ism — into Python. It is like running on marbles with scissors. No stability and potential for loss of precious runtime fluids.
In a debugging context, though, being able to turn an id() back into an object reference allows interrogation of objects where identification of “objects of interest” and the actual interrogation of said objects does not have to happen within a contiguous set of expressions.
Chris says:
I wish people wouldn’t post stuff like this. There is never any case where this is a useful operation - the only time it works is when the object you want to retrieve is still around anyway - and there’s never any reason to store the id of an object instead of the object reference (or a weakref) instead.
People asking how to do this isn’t uncommon, and being able to google for it will just lead people to doing it instead of being told that they need to fix the problem that leads to them wanting to do it instead.
“Never any case”? That is a bit unimaginative and could even be construed as arrogant. The only safe “never” is in the statement “never assume you know everything”.
Sure — if you pass a random number or the id of a no longer existing object to di(), your process is going to crash. Totally true and I have added some emphasis on exactly why this feature is not a part of python, nor should it be.
As for this tool and the dangers therein: So what? Don’t do that. Tools can be misused. If something hurts, don’t do it.
This tool has saved me hours and hours of engineering time, several hundred lines of fairly complex code, and having to make some fairly nasty & intrusive changes to several relatively complex client/server focused codebases. More subtly, it allowed me to vastly reduce memory leaks without having to instrument the code in ways that would have very likely changed the lifespan of objects.
Lame. Python’s weakrefs don’t support weak references to Dictionaries, Lists, Tuples, Strings, or None. Four out of five of these types are very often exactly the kind of thing I need to figure out why there are tons of ‘em floating around that shouldn’t be. Bogus.











