如何在Python中判断对象是否被删除

6

我在堆中有一个对象和一个指向它的引用。在某些情况下,对象被删除,但指向其位置的引用不知道这一点。如何检查堆中是否存在真正的数据?

例如:

from PySide import *
a = QProgressBar()
b = QProgressBar()
self.setIndexWidget(index,a)
self.setIndexWidget(index,b)

然后 a 对象被删除了,但是 print(a) 返回一个有效的地址。然而,如果你尝试调用 a.value(),会出现运行时错误(C++ 对象已经被删除)。

a is None 返回 False

3个回答

16

要查询 PySide 对象,您需要使用 shiboken 模块。对于 Pyside2,您需要使用 shiboken2

import shiboken  # shiboken2

print shiboken.isValid(a)

3
谢谢你的提问!但是我该在哪里找到shiboken模块呢?Pyside维基已经无法使用了。我从源代码构建了Pyside,只找到了shiboken-python2.7.dll文件,但没有shiboken pyd文件。 - jichi
应该可以使用“from Shiboken import shiboken”进行导入。请参见:http://stackoverflow.com/questions/25458572/shiboken-cannot-be-imported/25935614#25935614 - eric
3
快速更新,对于 PySide2,现在可用 shiboken2.isValid() - Green Cell
或者如果使用 Qt.py - QtCompat.isValid() - Peter

5

使用 sip 模块,更多关于 sip 的信息请在这里查看。

import sip

a = QProgressBar()
sip.isdeleted(a)
False

sip.delete(a)
a
<PyQt4.QtCore.QObject object at 0x017CCA98>

sip.isdeleted(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: underlying C/C++ object has been deleted

sip.isdeleted(a) 在对象被删除时返回 True,而不会引发任何异常。 - andrean
这里显示的输出是错误的:sip.isdeleted(a)永远不会引发该运行时错误。 - ekhumoro
@ekhumoro 这是一个六年前的回答,也许现在情况已经改变了。 :) - Ashwini Chaudhary
1
@AshwiniChaudhary 嗯,这只是暗示以改进你的答案; -)(如果“isdelete”曾经引发异常,那显然是一个已经被修复的错误)。 - ekhumoro

0
文档明确指出当一个对象负责删除另一个对象时。在您的示例中,您可以在Qt doc中看到这一点:

如果索引小部件A被索引小部件B替换,则索引小部件A将被删除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接