Python QStandardItem缺少散列方法

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" >>

我发现,当将一些Python2/Qt4代码转换为Python3/Qt5时,QStandardItem显然不能再用作dict键,因为它没有实现
\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)

    可能是一个问题?