我可以在Python中使用对象(类的实例)作为字典键吗?
我想用一个类的实例作为字典的键,比如:
classinstance = class()
dictionary[classinstance] = 'hello world'
看起来Python不支持把类作为字典的键,难道我理解错了吗?另外,我可以用一个元组列表,比如[(类实例, "你好,世界"),...]来代替字典,但这样看起来很不专业。你有什么建议可以解决这个问题吗?
5 个回答
5
试着在你的类里实现 hash 和 eq 这两个方法。
比如,这里有一个我写的简单的可哈希字典类:
class hashable_dict:
def __init__(self, d):
self.my_dict = d
self.my_frozenset = frozenset(d.items())
def __getitem__(self, item):
return self.my_dict[item]
def __hash__(self):
return hash(self.my_frozenset)
def __eq__(self, rhs):
return isinstance(rhs, hashable_dict) and self.my_frozenset == rhs.my_frozenset
def __ne__(self, rhs):
return not self == rhs
def __str__(self):
return 'hashable_dict(' + str(self.my_dict) + ')'
def __repr__(self):
return self.__str__()
6
下面的代码运行得很好,因为默认情况下,你的类对象是可以被哈希的:
Class Foo(object):
def __init__(self):
pass
myinstance = Foo()
mydict = {myinstance : 'Hello world'}
print mydict[myinstance]
输出:
你好,世界
另外,如果你想了解更高级的用法,可以看看这篇文章:
16
你的实例需要是可哈希的。根据Python 词汇表的解释:
一个对象是可哈希的,如果它有一个在整个生命周期内都不会改变的哈希值(这需要一个
__hash__()
方法),并且可以与其他对象进行比较(这需要一个__eq__()
或__cmp__()
方法)。那些比较相等的可哈希对象必须有相同的哈希值。可哈希性使得一个对象可以用作字典的键和集合的成员,因为这些数据结构在内部使用哈希值。
所有Python内置的不可变对象都是可哈希的,而可变容器(比如列表或字典)则不是。用户自定义类的实例默认是可哈希的;它们之间比较都是不相等的,哈希值就是它们的id()。