我发现在将一些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__
的一个简单版本(我已经做过了)。但我有什么遗漏吗?在
在Qt中,有三个requirements for hashability:
==
运算符qHash
函数因此,如果PyQt想保持与Qt的一致性,那么它只应该在上述条件适用时定义
__hash__
,并且它的实现应该简单地委托给Qt提供的qHash
函数。在在python2和PyQt4/5中使用python2时的行为应该被认为是一种错误的特性,因为它给出的结果与Qt不一致。这可以通过查看是散列的类型(用Qt术语)的情况来了解:
使用Python 3:
这正是我们想要的:那些compare相等的对象也应该hash相等。但是现在看看在python2中使用相同版本的PyQt时会发生什么:
^{pr2}$python2中的
__hash__
实现似乎使用了类似对象的identity,这显然与Qt的散列语义不一致。在在Qt中,
QStandardItem
类的从未是散列的,因此为了一致性起见,PyQt现在选择不为它提供__hash__
方法。而且由于QStandardItem
的实例实际上是可变的,PyQt相当合理地让用户决定何时定义__hash__
,以及如何实现它。为了与Python2兼容,这可能只返回id(self)
。在相关问题 更多 >
编程相关推荐