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


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

def itemChangedSlot(epw, item):
    new_data = item.data()
    print new_data
    print item

打印

<PyQt4.QtGui.QStandardItem object at 0x07C5F930>
<PyQt4.QtCore.QVariant object at 0x07D331F0>

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


12233
2018-04-01 18:12


起源

物体 new_data 您正在打印的是对象。只需返回或以其他方式存储而不是打印它。 - BrenBarn
不是 不可能 要做到这一点,但这并不容易,而且在任何情况下都无法记录,而且这通常是一个非常糟糕的主意。如果你正在试验CPython如何在幕后工作,或调试垃圾收集器,或类似的东西,它可能是值得做的,但除此之外,你正在咆哮错误的树,而Raymond Hettinger的回答就是你想要的。 - abarnert


答案:


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

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

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

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

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

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

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

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

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

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


8
2018-04-01 18:50





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

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


8
2018-04-01 18:17