Is it possible to get the Physical memory address of a variable in python?

Chris Angelico rosuav at gmail.com
Mon Jan 23 15:17:32 EST 2017


On Tue, Jan 24, 2017 at 6:05 AM, Skip Montanaro
<skip.montanaro at gmail.com> wrote:
> On Mon, Jan 23, 2017 at 12:49 PM, Chris Angelico <rosuav at gmail.com> wrote:
>>
>> On Tue, Jan 24, 2017 at 4:49 AM, Sourabh Kalal <kalalsunnyy at gmail.com> wrote:
>> > how we can access the value from using id..
>> > like x=10
>> > id(x)
>> > 3235346364
>> >
>> > how i can read value 10 using id 3235346364
>>
>> No, you can't. That isn't a memory address - it's just a unique
>> identifier. Python doesn't have memory addresses.
>
> Well, it might be, but that would be very implementation-dependent.
> Any attempt to treat an id as a memory address and interpret the
> object at that address as the beginning of a PyObject of any kind will
> be fragile in the extreme. Even if you have two different
> implementations at hand which both use memory addresses as convenient
> ids, there's no guarantee that the address represents that start of a
> CPython PyObject.
>
>>>> hex(3235346364)
> '0xc0d777bc'
>
> There. *Now* you have an address. Hack to your heart's content. <wink>

No, you now have a hexadecimal representation of an integer. Memory
addresses are integers; Python object identifiers are also integers.
The fact that they may happen to correspond *in CPython* is basically
a coincidence.

In a language like C, where pointers and memory addresses are real
things, you can work with an integer and dereference it to get the
data at that address. In BASIC, where I first learned programming, you
have specific instructions to mess with memory (I have fond memories
of messing around with segment zero to change the status of Caps Lock
etc, and of peeking and poking in video memory, and stuff). But in
Python, that exists only in ctypes, and that only because ctypes is
basically C.

rosuav at sikorsky:~$ python3
Python 3.7.0a0 (default:cebc9c7ad195, Jan 24 2017, 06:55:19)
[GCC 6.2.0 20161027] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> objs = [object() for _ in range(10)]
>>> [id(x) for x in objs]
[140652901773504, 140652901773520, 140652901773536, 140652901773552,
140652901773568, 140652901773584, 140652901773600, 140652901773616,
140652901773632, 140652901773648]

These could well be memory addresses, but...

>>> objs = [object() for _ in range(10)]
>>> [id(x) for x in objs]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

... these almost certainly aren't. They are, however, unique integer
values (the 'objs' list guarantees that all objects are simultaneously
alive, ergo the IDs must be unique). Other Python implementations are
free to do what they like. Quite a few do seem to use something like a
memory address (uPy, PyPy, PyPyJS), but not all:

Brython 3.3.0 on Netscape 5.0 (X11; Linux x86_64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
>>> objs = [object() for _ in range(10)]
>>> [id(x) for x in objs]
[54, 55, 56, 57, 58, 59, 60, 61, 62, 63]

There's basically no way to go from an ID to the object. If you know
what data type it is (eg an integer, as in the OP's example), you can
reach in and grab the contents, but there's no way to write this
function:

def deref(id):
    ... # ????
assert deref(id(x)) is x

The best you could do, in terms of parlour tricks, is to test it only
on small integers, where ctypes can get you the value of the integer,
and thanks to small-int-caching, it will actually be the same object.
But it won't work for larger integers.

It's not a pointer.

ChrisA


More information about the Python-list mailing list