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

4 投票
3 回答
1177 浏览
提问于 2025-04-16 23:56

在CPython中,内置函数 id(x) 会返回 x 的内存地址。
那么,有没有办法反过来做呢?

比如说 object_by_memoryadress(id(x)) == x 这样的方式。

更新: 我需要这样做的原因是,我在使用一个嵌入了Python的程序。在这个程序中,我可以创建所谓的“节点”,这些节点可以相互通信,但只能用整数、字符串等基本类型。不过,我需要在它们之间“传递”一个列表(而这通常是做不到的)。

3 个回答

1

我从来没有见过可以做到那样的函数。不过,你可以自己维护一个内部索引,记录你创建的每个对象,并存储它们的内存地址。然后你可以在这个表格里查找。

3

如果你的目标是让不同的Python程序同时运行并互相传递信息,可以看看multiprocessing或者celery。

如果你只是想保存、恢复或者传递一些任意的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()做同样的事情。正如你在上面看到的,如果你在遍历作用域的命名空间时创建了一个新的名字,这样做是行不通的。可能还有很多其他问题。

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

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)

撰写回答