Access Memory Address in Python

Accessing Object Memory Address

The Python manual has this to say about id():

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.

Possible to get value of address in python?

it adds the integer, assigns that resultant value to a new memory address

No; the object that represents the resulting value has a different memory address. Typically this object is created on the fly, but specifically for integers (which are immutable, and for some other types applying a similar optimization) the object may already exist and be reused.

Is there a way to see what the value is at the (old) memory address 4304852448 (0x10096d5e0) is?

This question is not well posed. First off, "memory addresses" in this context are virtualized, possibly more than once. Second, in the Python model, addresses do not "have values". They are potentially the location of objects, which in turn represent values.

That said: at the location of the previous id(a), the old object will still be present if and only if it has not been garbage-collected. For this, it is sufficient that some other reference is held to the object. (The timing of garbage collection is implementation-defined, but the reference CPython implementation implements garbage collection by reference counting.)

You are not, in general, entitled to examine the underlying memory directly (except perhaps with some kind of process spy that has the appropriate permissions), because Python is just not that low-level of a language. (As in @xprilion's answer, the CPython implementation provides a lower-level memory interface via ctypes; however, the code there is effectively doing an unsafe cast.)

If you did (and assuming CPython), you would not see a binary representation of the integer 100 in the memory location indicated by calling id(a) the first time - you would see instead the first word of the PyObject struct used to implement objects in the C code, which would usually be the refcount, but could be a pointer to the next live heap object in a reference-tracing Python build (if I'm reading it correctly).

Once it's garbage-collected, the contents of that memory are again undefined. They depend on the implementation, and even specifically for the C implementation, they depend on what the standard library free() does with the memory. (Normally it will be left untouched, because there is no reason to zero it out and it takes time to do so. A debug build might write special values into that memory, because it helps detect memory corruption.)

print memory address of Python variable

id is the method you want to use: to convert it to hex:

hex(id(variable_here))

For instance:

x = 4
print hex(id(x))

Gave me:

0x9cf10c

Which is what you want, right?

(Fun fact, binding two variables to the same int may result in the same memory address being used.)

Try:

x = 4
y = 4
w = 9999
v = 9999
a = 12345678
b = 12345678
print hex(id(x))
print hex(id(y))
print hex(id(w))
print hex(id(v))
print hex(id(a))
print hex(id(b))

This gave me identical pairs, even for the large integers.

how to get memory location of a variable in Python

You can’t, but the reason is so fundamental that I think it worth posting anyway. In C, a pointer can be formed to any variable, including another pointer. (Another pointer variable, that is: you can write &p, but not &(p+1).) In Python, every variable is a pointer but every pointer is to an object.

A variable, not being an object, cannot be the referent of a pointer. Variables can however be parts of objects, accessed either as o.foo or o[bar] (where bar might be an index or a dictionary key). In fact, every variable is such an object component except a local variable; as a corollary, it is impossible to assign to a local variable from any other (non-nested) function. By contrast, C does that regularly by passing &local to whatever other function.

This distinction is readily illustrated by C++ containers: they typically provide operator[] to return a reference (a pointer that, like a Python reference, is automatically dereferenced) to an element to which = can be applied, whereas the Python equivalent is to provide both __getitem__ (to return a reference) and __setitem__ (which implements []= all at once to store to a variable).

In CPython’s implementation, of course, each Python variable is a PyObject* variable, and a PyObject** to one can be used for internal purposes, but those are always temporary and do not even conceptually exist at the Python level. As such, there is no equivalent for id for them.

How can I change the value of an memory-address in Python?

You can try to use the ctypes library. Try this,

import ctypes

data = (ctypes.c_char).from_address(0x0195A810)

You can read and assign to the data variable. Make sure you select the correct type. I used char in this instance. Not sure what kind of value is stored there. You can see what types are available in the link below.

You can also get a list/array of memory addresses using this,

dataarr = (ctypes.c_char*offset).from_address(0x0195A810)

You can check out the documentation here,

https://docs.python.org/3/library/ctypes.html

Can I access memory location and values ( pointers and reference ) for variables in a loop, in Python 3

Assuming you're a beginner to Python

What you want is a dictionary or a list. Use a dictionary if you need the variable names, but in this case a list is probably a better idea.

Dictionary sample implementation:

nums={
"my_1": 10,
"my_2": 20,
} #Create a dictionary of your nums

print(nums["my_1"]) #10
print(nums["my_2"]) #20

for num in nums: #Iterate through the keys of the dictionary
nums[num] = 5 #and set the values paired with those keys to 5

print(nums["my_1"]) #5
print(nums["my_2"]) #5

List sample implementation:

nums = [10, 20] #Create a list and populate it with your numbers

print(nums[0]) #10
print(nums[1]) #20

for num in range(len(nums)): #Keys for your list
nums[num] = 5 #Set the values within the list

print(nums[0]) #5
print(nums[1]) #5

Assuming you're a moderately advanced programmer

You can mutate the globals() dict.

my_num_1 = 10
my_num_2 = 20

print(my_num_1) #10
print(my_num_2) #20

for name in ("my_num_1", "my_num_2"): #Iterate through a tuple of your names
globals()[name] = 5 #and mutate the globals dict

print(my_num_1) #5
print(my_num_2) #5


Related Topics



Leave a reply



Submit