[英]QStandardItem missing __hash__ method
我發現在將一些 Python2/Qt4 代碼轉換為 Python3/Qt5 時,顯然 QStandardItem 不能再用作字典鍵,因為它沒有實現__hash__
,因此不再被認為是不可變的。
這兩個片段顯示了問題:
PyQt4:
>>> from PyQt4 import QtGui
>>> a = QtGui.QStandardItem()
>>> b = {}
>>> b[a] = "1"
>>> a.__hash__()
2100390
PyQt5:
>>> 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__
的簡單版本(我已經完成了)。 但是有什么我想念的嗎?
在 Qt 中,對 hashability有三個要求:
==
運算符qHash
函數所以如果 PyQt 想要保持與 Qt 的一致性,它應該只在滿足上述條件時定義__hash__
,並且它的實現應該簡單地委托給 Qt 提供的任何qHash
函數。
使用Python 2 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
似乎 Python 2 中的__hash__
實現使用了類似於對象標識的東西,這顯然永遠不會與 Qt 的散列語義一致。
QStandardItem
類在 Qt 中從未可散列,因此為了一致性,PyQt 現在選擇不為其提供__hash__
方法。 由於QStandardItem
實例實際上是可變的,PyQt 相當合理地讓用戶決定何時定義__hash__
以及如何實現它。 為了與 Python 2 兼容,這可能只返回id(self)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.