我正在尝试构建一个对象的一组实例,但是添加某些对象的实例会导致 TypeError: unhashable instance。这是一个最小的例子:
from sets import Set
import random
from UserDict import DictMixin
class Item1(object):
pass
class Item2(DictMixin):
pass
item_collection = Set()
x = Item1()
y = Item2()
item_collection.add(x) # this works
print item_collection
item_collection.add(y) # this does not
print item_collection
为什么会失败,我怎样才能得到一组从 DictMixin 派生的对象的实例?
请您参考如下方法:
如果你愿意,你的类可以定义 __hash__和比较方法(最重要的是 __eq__ )彼此一致且“稳定”——即,两个对象的相等性在对象的生命周期内不能变化,当然每个对象的哈希值也不能在整个生命周期内变化对象的生命周期。
一致性要求是:a==b 必须暗示hash(a)==hash(b) (相反的情况不一定成立,而且实际上很少成立)。
因此,如果您满足这些要求,最简单的实现方式是:
class Item2(DictMixin):
def __hash__(self): return hash(id(self))
def __eq__(self, x): return x is self
def __ne__(self, x): return x is not self
碰巧这也会自动与您的 Item1 互操作类,因为这是不继承或定义其他版本的类的散列和比较的默认实现(因为您从 __eq__ 继承了不同版本的 DictMixin,除非您再次覆盖它)。
x is self是 id(x) == id(self) 更快、更直接、更简洁的表达方式, 因为 that 是 is 的意思运算符——id 的身份(即,相同的对象)。
事实也是 a==b因此被迫与 a is b 表示相同的意思您的应用程序有问题吗?如果是这样,那么集合就不能用于所述应用程序,你需要考虑其他一些完全不同的数据结构(一个不基于散列的数据结构,因为没有 __eq__ 覆盖你不能使散列正确工作)。
