当我自定义类时,如果定义了__eq__方法,这个类的对象会变成unhashable。以下是在python3.6中的情况:
1 | class Item: |
排查
以下内容引用自python3手册的object.__hash__部分
If a class does not define an __eq__() method it should not define a __hash__() operation either; if it defines __eq__() but not __hash__(), its instances will not be usable as items in hashable collections. If a class defines mutable objects and implements an __eq__() method, it should not implement __hash__(), since the implementation of hashable collections requires that a keys hash value is immutable (if the objects hash value changes, it will be in the wrong hash bucket).
翻译成中文如下:
如果一个类没有定义__eq __()方法,那么它也不应该定义__hash __()操作。如果它定义__eq __()但不定义__hash __(),则其实例将不能用作可哈希集合中的项目。如果一个类定义了可变对象并实现了__eq __()方法,则不应实现__hash __(),因为可哈希集合的实现要求键的哈希值是不可变的(如果对象的哈希值发生变化,那将是错误的哈希存储桶)
综上,如果定义 __eq__
,默认的__hash__
将消失。
这是因为相等对象的哈希值一定相等,如果__hash__
不消失,则会出现相等对象的哈希值不相等的情况。
解决
解决方法很简单,在定义__eq__
方法的同时定义__hash__
方法即可,如下:
1 | class Item: |