将功能移植到程序的Python 3.1 fork时遇到一个奇怪的错误。我将其缩小为以下假设:
与Python 2.x相比,在Python 3.x中,如果对象具有__eq__方法,则该对象将自动取消哈希。
__eq__
这是真的?
这是Python 3.1中发生的情况:
>>> class O(object): ... def __eq__(self, other): ... return 'whatever' ... >>> o = O() >>> d = {o: 0} Traceback (most recent call last): File "<pyshell#16>", line 1, in <module> d = {o: 0} TypeError: unhashable type: 'O'
后续问题是,如何解决我的个人问题?我有一个对象ChangeTracker,该对象存储一个WeakKeyDictionary指向多个对象的对象,并为每个对象提供过去某个特定时间点的酱菜堆的值。每当检入现有对象时,变更跟踪器都会说出其新的泡菜与旧的泡菜是否相同,因此说明对象在此同时是否发生了变化。问题是,现在我什至无法检查给定的对象是否在库中,因为这使它引发有关该对象不可哈希的异常。(因为它有一种__eq__方法。)如何解决此问题?
ChangeTracker
WeakKeyDictionary
是的,如果您定义__eq__,则默认值__hash__(即对内存中对象的地址进行哈希处理)将消失。这很重要,因为散列必须与相等性保持一致:相等的对象需要对散列进行相同的散列。
__hash__
解决方案很简单:只需将define__hash__和define一起定义即可__eq__。