哈希Python类是一个好主意吗?

时间:2009-08-26 15:27:16

标签: python class inheritance hash dictionary

例如,假设我这样做:

>>> 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散列。

这种行为是否可靠,或者这里有任何陷阱?

2 个答案:

答案 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__以按值进行比较并允许其值变异的类不能在哈希集合中使用。