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

问题描述 投票:0回答:3

在 CPython 中,内置函数

id(x)
返回
x
的内存地址。
可以逆转吗?

类似

object_by_memoryadress(id(x)) == x

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

python cpython
3个回答
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()
重复此操作。正如您在上面所看到的,如果您在迭代作用域的命名空间时在作用域中创建新名称,则该方法不起作用。它可能还以其他十几种方式被破坏。

不要这样做,这是错误的而且不好!


1
投票

我从来没有遇到过可以做到这一点的函数。但是您可以保留创建的每个对象的内部索引并存储它及其内存地址。然后在表中查找。


1
投票

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

#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对象的内存地址交换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)
© www.soinside.com 2019 - 2024. All rights reserved.