I have a function to retrieve an object in Python using the ctypes module:
import ctypes
def object_at_addr(obj_addr):
try:
val = ctypes.cast(obj_addr, ctypes.py_object).value
except:
return None
return val
I know that the id
of an object shows the memory address the object is at (for the most part as far as I've seen with builtins and custom objects). On my terminal shell, I tried this on the number 0 and "recursively" found the id
of each number to see if it was cyclic in some form. Here is the terminal output:
>>> id(0) # num1
4343595216
>>> id(4343595216) # num2
4344636112
>>> id(4344636112) # num3
4344636112
To my surprise, the id of two numbers were the same. However, when I use my function and call object_at_addr(4344636112)
, it doesn't point to either number, but instead returned a different int value as shown below:
>>> object_at_addr(4344636112)
4411205344
How can two different numbers have the same id value? Does the id
function actually return the memory address for all objects, or is it only for custom objects, or is it just a Python design choice to make the memory address the id
of an object, but it's different for builtin objects?
The id
is always the memory address in the CPython implementation. The reason that you saw numbers with the same id here is that memory addresses can be re-used. The id is only guaranteed to be unique for the lifetime of the object, and since nothing else was holding a reference to the integer 4343595216
it got deleted immediately after the function call returns. That memory location was freed, and then immediately reused by the integer 4344636112
instance.
The docs actually mention this explicitly:
Two objects with non-overlapping lifetimes may have the same
id()
value.