是否可以通过内存地址访问对象?

时间:2011-08-19 08:56:00

标签: python cpython

在CPython中,内置函数id(x)返回x的内存地址。
有可能扭转这种局面吗?

类似于object_by_memoryadress(id(x)) == x

更新:我需要这个的原因是,因为我正在使用嵌入式Python的程序。在这个程序中,我可以创建所谓的“节点”,它们可以相互通信,但只能用整数,字符串和东西,但我需要在它们之间“传输”一个列表(这是不可能的通常方式)。

3 个答案:

答案 0 :(得分:2)

如果您的目标是在同时运行的不同Python进程之间发送信息,请查看multiprocessing或芹菜。

如果您只是希望能够保存/恢复/传递任意Python对象,请查看picklemarshal

不要这样做,这是错误的和坏的!

>>> x = 'asdd3r3'
>>> b = id(x)
>>> for key, value in globals().iteritems():
...     if id(value) == b:
...         break
...
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
>>> for key, value in globals().iteritems():
...     if id(value) == b:
...         break
...
>>> print value
asdd3r3
>>>

您还必须为locals()重复此操作。如您所见,如果您在范围的命名空间中迭代时在范围中创建新名称,则它不起作用。它可能还会以其他方式被打破。

不要这样做,这是错误的和坏的!

答案 1 :(得分:1)

我从未遇到过能够做到这一点的功能。但是你可以保留你创建的每个对象的内部索引并存储它以及它的内存地址。然后在表格中查找。

答案 2 :(得分:0)

我创建了一个包含以下代码的共享库:

#include "Python.h"
extern "C" __declspec(dllexport) PyObject* PyObjectFromAdress(long addr) {
    return (PyObject*) addr;
}

编译它并使用ctypes包装它:

import ctypes
dll = ctyes.cdll.thedll
object_from_id = dll.PyObjectFromAdress
object_from_id.restype = ctypes.py_object()

现在你可以在一个python进程中通过内存地址交换python对象。

l1 = []
l2 = object_from_id( id(l1) )
print l1 == l2
l1.append(9)
print l2

但要注意已经垃圾收集的对象!以下代码将使Python解释器崩溃。

l2 = object_from_id( id([]) )
l2.append(8)