16

我正在学习如何将 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 上没有看到任何内容,也许我的术语不对?

4

2 回答 2

16

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

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

于 2013-04-01T18:17:18.903 回答
11

你几乎肯定问错了问题,而 Raymond Hettinger 的答案几乎肯定是你真正想要的。

尝试深入研究 CPython 解释器的内部结构以用于学习目的或对其进行审计以查找安全漏洞或其他东西时,这样的事情可能很有用……但即便如此,您最好还是将 Python 解释器嵌入到程序中并编写暴露的函数任何你想要的 Python 解释器,或者至少编写一个 C 扩展模块,让你操作 CPython 对象。

但是,如果你真的需要这样做……</p>

首先,甚至没有可靠的方法从repr. 大多数具有有用eval-able 表示的对象都会为您提供。例如,repr 的('1', 1)is "('1', 1)", not <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 解释器崩溃比做任何有用的事情要容易得多,但做任何有用的事情也不是不可能的,你可能会喜欢用它做实验。

于 2013-04-01T18:50:30.240 回答