Python QStandardItem缺少散列方法
我发现,当将一些Python2/Qt4代码转换为Python3/Qt5时,QStandardItem显然不能再用作dict键,因为它没有实现Python QStandardItem缺少散列方法,python,qt,hash,pyqt,qstandarditem,Python,Qt,Hash,Pyqt,Qstandarditem,我发现,当将一些Python2/Qt4代码转换为Python3/Qt5时,QStandardItem显然不能再用作dict键,因为它没有实现\uuuuuuuuuuuuuuuu散列,因此不再被认为是不可变的 这两个片段说明了问题: PyQt4: >>> from PyQt4 import QtGui >>> a = QtGui.QStandardItem() >>> b = {} >>> b[a] = "1" >>
\uuuuuuuuuuuuuuuu散列,因此不再被认为是不可变的
这两个片段说明了问题:
PyQt4:
>>> from PyQt4 import QtGui
>>> a = QtGui.QStandardItem()
>>> b = {}
>>> b[a] = "1"
>>> a.__hash__()
2100390
>>> from PyQt5 import QtGui
>>> a = QtGui.QStandardItem()
>>> b = {}
>>> b[a] = "1"
TypeError: unhashable type: 'QStandardItem'
>>> a.__hash__()
TypeError: 'NoneType' object is not callable
PyQt5:
>>> from PyQt4 import QtGui
>>> a = QtGui.QStandardItem()
>>> b = {}
>>> b[a] = "1"
>>> a.__hash__()
2100390
>>> from PyQt5 import QtGui
>>> a = QtGui.QStandardItem()
>>> b = {}
>>> b[a] = "1"
TypeError: unhashable type: 'QStandardItem'
>>> a.__hash__()
TypeError: 'NoneType' object is not callable
为什么要改变?我应该不使用QStandardItem作为dict键吗
显而易见的解决办法是将QStandardItem子类化,并重新实现一个简单版本的\uuuuhash\uuuuuuu
(我已经完成了)。但是我有什么遗漏吗?在Qt中,有三个:
该类型必须是可分配的数据类型
类型必须定义一个=
运算符
必须为类型定义qHash
函数
因此,如果PyQt想要保持与Qt的一致性,那么当上述条件适用时,它应该只定义\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
将Python2与PyQt4/5一起使用时的行为可能被认为是一种错误特性,因为它给出的结果与Qt不一致。这可以通过查看可散列的类型(用Qt表示)发生的情况来看出:
使用Python 3:
>>> a = QtCore.QUrl('foo.bar')
>>> b = QtCore.QUrl('foo.bar')
>>> a == b
True
>>> hash(a) == hash(b)
True
这正是我们想要的:比较相等的对象也应该散列相等。但是现在看看在Python 2上使用相同版本的PyQt时会发生什么:
>>> a = Qt.QUrl('foo.bar')
>>> b = Qt.QUrl('foo.bar')
>>> a == b
True
>>> hash(a) == hash(b)
False
Python2中的\uuuuu hash\uuuu
实现似乎使用了类似对象标识的东西,这显然与Qt的哈希语义不一致
Qt中的QStandardItem
类从来都不是可散列的,因此为了一致性,PyQt现在选择不为其提供\uuuuuuhash\uuuu
方法。而且由于QStandardItem
的实例实际上是可变的,因此PyQt相当合理地让用户决定何时定义\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu散列以及如何实现它。为了与Python2兼容,这可能只是返回id(self)
可能是一个问题?