例如,假设我这样做:
>>> class foo(object):
... pass
...
>>> class bar(foo):
... pass
...
>>> some_dict = { foo : 'foo',
... bar : 'bar'}
>>>
>>> some_dict[bar]
'bar'
>>> some_dict[foo]
'foo'
>>> hash(bar)
165007700
>>> id(bar)
165007700
基于此,看起来该类正在进行哈希作为其ID号。因此,如果我改变了类bar
或者foo
或哈希值发生变化,那么就不应该担心担心bar
散列。
这种行为是否可靠,或者这里有任何陷阱?
答案 0 :(得分:8)
是的,任何未实现__hash__()
函数的对象都会在哈希时返回其id。来自Python Language Reference: Data Model - Basic Customization:
默认情况下,用户定义的类具有
__cmp__()
和__hash__()
方法;与他们一起,所有对象比较不等(除了他们自己)和x.__hash__()
返回id(x)
。
但是,如果您希望获得唯一标识符,请使用id
来明确您的意图。对象的哈希应该是其组件的哈希的组合。有关详细信息,请参阅上面的链接。
答案 1 :(得分:6)
类具有__eq__
和__hash__
的默认实现,它们分别使用id()
进行比较和计算哈希值。也就是说,他们按身份进行比较。实现__hash__
方法的主要规则是,如果两个对象相互比较相等,则它们也必须具有相同的哈希值。散列值可以看作是dicts和sets使用的优化,可以更快地找到相等的对象。因此,如果您更改__eq__
以执行其他类型的相等测试,则还必须更改__hash__
实施以同意该选择。
使用身份进行比较的类可以自由地变异并在dicts和sets中使用,因为它们的身份永远不会改变。实现__eq__
以按值进行比较并允许其值变异的类不能在哈希集合中使用。