With this block of code you can get the contents of variable x based on its memory address:

from ctypes import string_at

x = 14
print(string_at(id(x) + 24))

Keep in mind that id(x) returns the memory address where x has been stored. We have to add 24 to the memory address of x to get the value of it because an int object has 24 bytes of metadata.

For larger integers than what an int32_t can hold, we have to use a different method.

import ctypes

x = 32871637867213678216387612736

int_at = lambda addr, size: int.from_bytes(ctypes.string_at(addr, size), 'little')

def compute_large(x):
    size = int_at(id(x) + 16, 8)
    res = 0
    for i in reversed(range(size)):
        res = res << 30 | int_at(id(x) + 24 + i * 4, 4)
    return res

assert compute_large(x) == x

If this fails for you, you might want to change 'little' to 'big'

For str objects though, there’s 48 bytes of metadata.

x = 'Hello World!'
print(string_at(id(x) + 48))    

Summary

Every object in Python has a big metadata