When you call the
object.__repr__() method in Python you get something like this back:
<__main__.Test object at 0x2aba1c0cf890>
Is there any way to get a hold of the memory address if you overload
__repr__(), other then calling
super(Class, obj).__repr__() and regexing it out?
The Python manual has this to say about
Return the “identity” of an object.
This is an integer (or long integer)
which is guaranteed to be unique and
constant for this object during its
lifetime. Two objects with
non-overlapping lifetimes may have the
same id() value. (Implementation note:
this is the address of the object.)
So in CPython, this will be the address of the object. No such guarantee for any other Python interpreter, though.
Note that if you’re writing a C extension, you have full access to the internals of the Python interpreter, including access to the addresses of objects directly.
You could reimplement the default repr this way:
def __repr__(self): return '<%s.%s object at %s>' % ( self.__class__.__module__, self.__class__.__name__, hex(id(self)) )
There are a few issues here that aren’t covered by any of the other answers.
id only returns:
the “identity” of an object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same
In CPython, this happens to be the pointer to the
PyObject that represents the object in the interpreter, which is the same thing that
object.__repr__ displays. But this is just an implementation detail of CPython, not something that’s true of Python in general. Jython doesn’t deal in pointers, it deals in Java references (which the JVM of course probably represents as pointers, but you can’t see those—and wouldn’t want to, because the GC is allowed to move them around). PyPy lets different types have different kinds of
id, but the most general is just an index into a table of objects you’ve called
id on, which is obviously not going to be a pointer. I’m not sure about IronPython, but I’d suspect it’s more like Jython than like CPython in this regard. So, in most Python implementations, there’s no way to get whatever showed up in that
repr, and no use if you did.
But what if you only care about CPython? That’s a pretty common case, after all.
Well, first, you may notice that
id is an integer;* if you want that
0x2aba1c0cf890 string instead of the number
46978822895760, you’re going to have to format it yourself. Under the covers, I believe
object.__repr__ is ultimately using
%p format, which you don’t have from Python… but you can always do this:
format(id(spam), '#010x' if sys.maxsize.bit_length() <= 32 else '#18x')
* In 3.x, it’s an
int. In 2.x, it’s an
int if that’s big enough to hold a pointer—which is may not be because of signed number issues on some platforms—and a
Is there anything you can do with these pointers besides print them out? Sure (again, assuming you only care about CPython).
All of the C API functions take a pointer to a
PyObject or a related type. For those related types, you can just call
PyFoo_Check to make sure it really is a
Foo object, then cast with
(PyFoo *)p. So, if you’re writing a C extension, the
id is exactly what you need.
What if you’re writing pure Python code? You can call the exact same functions with
Finally, a few of the other answers have brought up
ctypes.addressof. That isn’t relevant here. This only works for
ctypes objects like
c_int32 (and maybe a few memory-buffer-like objects, like those provided by
numpy). And, even there, it isn’t giving you the address of the
c_int32 value, it’s giving you the address of the C-level
int32 that the
c_int32 wraps up.
That being said, more often than not, if you really think you need the address of something, you didn’t want a native Python object in the first place, you wanted a
Just in response to Torsten, I wasn’t able to call
addressof() on a regular python object. Furthermore,
id(a) != addressof(a). This is in CPython, don’t know about anything else.
from ctypes import c_int, addressof a = 69 addressof(a) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: invalid type b = c_int(69) addressof(b) 4300673472 id(b) 4300673392
With ctypes, you can achieve the same thing with
import ctypes a = (1,2,3) ctypes.addressof(a) 3077760748L
addressof(C instance) -> integer
Return the address of the C instance internal buffer
Note that in CPython, currently
id(a) == ctypes.addressof(a), but
ctypes.addressof should return the real address for each Python implementation, if
- ctypes is supported
- memory pointers are a valid notion.
Edit: added information about interpreter-independence of ctypes
You can get something suitable for that purpose with:
While it’s true that
id(object) gets the object’s address in the default CPython implementation, this is generally useless… you can’t do anything with the address from pure Python code.
The only time you would actually be able to use the address is from a C extension library… in which case it is trivial to get the object’s address since Python objects are always passed around as C pointers.