QStandardItem缺少哈希方法

2024-04-25 23:00:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我发现在将一些Python2/Qt4代码转换为Python3/Qt5时,QStandardItem显然不能再用作dict键,因为它没有实现__hash__,因此不再被认为是不可变的。在

这两个片段说明了问题:

PyQt4:

>>> from PyQt4 import QtGui
>>> a = QtGui.QStandardItem()
>>> b = {}
>>> b[a] = "1"
>>> a.__hash__()
2100390

PyQt5:

^{2}$

为什么要改变?我应该不使用QStandardItem作为dict键吗?在

显而易见的解决方法是将QStandardItem子类化并重新实现__hash__的一个简单版本(我已经做过了)。但我有什么遗漏吗?在


Tags: 方法代码fromimport版本hashdictpyqt5
1条回答
网友
1楼 · 发布于 2024-04-25 23:00:12

在Qt中,有三个requirements for hashability

  1. 类型必须是可分配的数据类型
  2. 类型必须定义==运算符
  3. 必须为类型定义qHash函数

因此,如果PyQt想保持与Qt的一致性,那么它只应该在上述条件适用时定义__hash__,并且它的实现应该简单地委托给Qt提供的qHash函数。在

在python2和PyQt4/5中使用python2时的行为应该被认为是一种错误的特性,因为它给出的结果与Qt不一致。这可以通过查看散列的类型(用Qt术语)的情况来了解:

使用Python 3:

>>> a = QtCore.QUrl('foo.bar')
>>> b = QtCore.QUrl('foo.bar')
>>> a == b
True
>>> hash(a) == hash(b)
True

这正是我们想要的:那些compare相等的对象也应该hash相等。但是现在看看在python2中使用相同版本的PyQt时会发生什么:

^{pr2}$

python2中的__hash__实现似乎使用了类似对象的identity,这显然与Qt的散列语义不一致。在

在Qt中,QStandardItem类的从未是散列的,因此为了一致性起见,PyQt现在选择不为它提供__hash__方法。而且由于QStandardItem的实例实际上是可变的,PyQt相当合理地让用户决定何时定义__hash__,以及如何实现它。为了与Python2兼容,这可能只返回id(self)。在

相关问题 更多 >