QStandardItem missing __hash__ method

后端 未结 1 1672
春和景丽
春和景丽 2021-01-19 15:52

I found when converting some Python2/Qt4 code to Python3/Qt5, that apparently QStandardItem can no longer be used as a dict key in as it doesn\'t have __hash__

相关标签:
1条回答
  • 2021-01-19 16:04

    In Qt, there are three requirements for hashability:

    1. the type must be an assignable data type
    2. the type must define an == operator
    3. a qHash function must be defined for the type

    So if PyQt wants to maintain consistency with Qt, it should only define __hash__ when the above conditions apply, and its implementation of it should simply delegate to whatever qHash function Qt provides.

    The behaviour when using Python 2 with PyQt4/5 should probably be considered a misfeature, because the results it gives are not consistent with Qt. This can be seen by looking at what happens with a type that is hashable (in Qt terms):

    Using Python 3:

    >>> a = QtCore.QUrl('foo.bar')
    >>> b = QtCore.QUrl('foo.bar')
    >>> a == b
    True
    >>> hash(a) == hash(b)
    True
    

    This is exactly what we want: objects that compare equal, should also hash equal. But now look at what happens when using the same version of PyQt with Python 2:

    >>> a = Qt.QUrl('foo.bar')
    >>> b = Qt.QUrl('foo.bar')
    >>> a == b
    True
    >>> hash(a) == hash(b)
    False
    

    It seems that something like the object's identity is used by the __hash__ implementation in Python 2, which obviously won't ever be consistent with Qt's hashing semantics.

    The QStandardItem class has never been hashable in Qt, so for the sake of consistency, PyQt now chooses not to provide a __hash__ method for it. And since instances of QStandardItem are, in fact, mutable, PyQt quite reasonably leaves it up to the user to decide when to define __hash__, and how to implement it. For compatibility with Python 2, this could probably just return id(self).

    0 讨论(0)
提交回复
热议问题