Reputation: 16900
In CPython, the builtin-function id(x)
returns the memory address of x
.
Is it possible to reverse this ?
Something like object_by_memoryadress(id(x)) == x
.
Update: The reason I need this is, because I'm using a program with embedded Python. And in this program I can create so called "Nodes" that can communicate with each other, but only with integers, strings, and stuff, but I'd need to "transfer" a list between them (which is not possible the usual way).
Upvotes: 5
Views: 1325
Reputation: 177000
If your goal is to send info between different Python processes running concurrently, check out multiprocessing or celery.
If you're just looking to be able to save / restore / pass around arbitrary Python objects, check out pickle and marshal.
The original method of doing this shared here was wrong and bad.
From @jsbueno's new answer, added here since this one sorts first:
import ctypes
def object_from_address(obj_id):
return ctypes.cast(obj_id, ctypes.py_object).value
Upvotes: 4
Reputation: 110821
One can use ctypes to cast the id (memory address of an object) into an object:
import ctypes
def object_from_address(obj_id):
return ctypes.cast(obj_id, ctypes.py_object).value
>>> a = [1, 2, 3]
>>> object_from_address(id(a)) is a
True
The .value
property from ctypes py_object increases the refcount of the target, so the object retrieved is safe to use.
However the remark about trying this on an freed-up object (i.e. the address of a no-longer existing object) remains true: one can crash the Python runtime doing this (or eventually, resuscitate a just deleted object: good luck with that)
Upvotes: 2
Reputation: 16900
I have created a shared library that contains the following code:
#include "Python.h"
extern "C" __declspec(dllexport) PyObject* PyObjectFromAdress(long addr) {
return (PyObject*) addr;
}
compiled it and wrapped it using ctypes:
import ctypes
dll = ctyes.cdll.thedll
object_from_id = dll.PyObjectFromAdress
object_from_id.restype = ctypes.py_object
Now you can exchange python objects through their memory adress within one python process.
l1 = []
l2 = object_from_id( id(l1) )
print l1 == l2
l1.append(9)
print l2
But be aware of already garbage collected objects ! The following code will crash the Python interpreter.
l2 = object_from_id( id([]) )
l2.append(8)
Upvotes: 1
Reputation:
I have never come across a function that could do that no. But you could keep an internal index of every object you create and store it as well as it's memory address. Then do a lookup in the table.
Upvotes: 1