我可以从其内存地址获取python对象吗?

Ero*_*mic 12 python ipython pyqt4 dereference

我正在学习如何将Qt与PyQt一起使用,我有一个带有StandardItemModel的QTabelView我已成功填充模型并将itemChanged信号连接到一个插槽.我想乱搞IPython中返回的任何对象,所以目前我有这条线:

def itemChangedSlot(epw, item):
    new_data = item.data()
    print new_data
    print item
Run Code Online (Sandbox Code Playgroud)

打印

<PyQt4.QtGui.QStandardItem object at 0x07C5F930>
<PyQt4.QtCore.QVariant object at 0x07D331F0>
Run Code Online (Sandbox Code Playgroud)

在IPython会话中是否可以使用此内存地址获取对象?我在Google上没有看到任何内容,也许我没有正确的术语?

Ray*_*ger 10

您需要保持对对象的引用(即将其分配给变量或将其存储在列表中).

从对象地址直接到对象(即指针解除引用)没有语言支持.


Ali*_*ati 9

我想答案就在这里。这样,我使用它的地址访问了一个对象:

import ctypes
myObj = ctypes.cast(0x249c8c6cac0, ctypes.py_object).value
Run Code Online (Sandbox Code Playgroud)


aba*_*ert 8

你几乎肯定会问错误的问题,Raymond Hettinger的回答几乎肯定是你真正想要的.

这样的东西可能有用,试图深入研究CPython解释器的内部用于学习目的或者为安全漏洞或其他东西进行审计......但即便如此,你最好将Python解释器嵌入到程序中并编写暴露的函数无论你想要什么进入Python解释器,或至少编写一个C扩展模块,让你操纵CPython对象.

但是,你真的需要这样做的机会......

首先,没有可靠的方法来获取地址repr.具有有用eval表示的大多数对象将为您提供相反的功能.例如,repr ('1', 1)"('1', 1)",而不是<tuple at 0x10ed51908>.此外,即使对于没有有用表示的对象,返回<TYPE at ADDR>也只是许多类型遵循的未声明约定(以及用户定义类的默认值),而不是您可以依赖的东西.

但是,既然你大概只关心CPython,你可以依靠id:

CPython实现细节:这是内存中对象的地址.

(当然如果你有调用id(或repr)的对象,你不需要通过指针取消引用它,如果你没有对象,它可能是垃圾收集所以没有什么可以取消引用,但也许你仍然有它,只是不记得你把它放在哪里...)

接下来,你用这个地址做什么?好吧,Python没有公开任何函数来做相反的事情id.但Python C API已有详细记录 - 如果您的Python是围绕共享库构建的,那么可以ctypes通过加载C API来访问它.实际上,ctypes提供了一个特殊的变量,可以自动加载正确的共享库来调用C API ctypes.pythonapi.

在非常旧的版本中ctypes,您可能必须明确地查找并加载它(例如pydll = ctypes.cdll.LoadLibrary('/usr/lib/libpython2.5.so'),这是用于安装在/ usr/lib中的Python 2.5的Linux;显然,如果这些细节中的任何一个不同,则确切的命令行会有所不同.)

当然,崩溃Python解释器要比做任何有用的东西要容易得多,但是做一些有用的事情并不是不可能的,你可以尝试使用它.