首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QStandardItem缺失__hash__方法

QStandardItem缺失__hash__方法
EN

Stack Overflow用户
提问于 2017-12-11 09:20:50
回答 1查看 430关注 0票数 4

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

这两个片段显示了问题所在:

PyQt4:

代码语言:javascript
复制
>>> from PyQt4 import QtGui
>>> a = QtGui.QStandardItem()
>>> b = {}
>>> b[a] = "1"
>>> a.__hash__()
2100390

PyQt5:

代码语言:javascript
复制
>>> from PyQt5 import QtGui
>>> a = QtGui.QStandardItem()
>>> b = {}
>>> b[a] = "1"
TypeError: unhashable type: 'QStandardItem'
>>> a.__hash__()
TypeError: 'NoneType' object is not callable

为什么要改变呢?我不应该使用QStandardItem作为一个丁字键吗?

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-11 20:25:15

在Qt中,有三个对可混性的要求

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

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

在PyQt4 4/5中使用Python2时的行为可能会被认为是错误的,因为它提供的结果与Qt不一致。这可以通过查看可访问类型(以Qt术语表示)所发生的情况来看出:

使用Python 3:

代码语言:javascript
复制
>>> a = QtCore.QUrl('foo.bar')
>>> b = QtCore.QUrl('foo.bar')
>>> a == b
True
>>> hash(a) == hash(b)
True

这正是我们想要的:比较相等的对象,也应该散列相等。但是现在看看在Python2中使用相同版本的PyQt时会发生什么:

代码语言:javascript
复制
>>> a = Qt.QUrl('foo.bar')
>>> b = Qt.QUrl('foo.bar')
>>> a == b
True
>>> hash(a) == hash(b)
False

Python2中的__hash__实现似乎使用了类似于对象的标识,这显然与Qt的散列语义不一致。

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47749631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档