2009-08-26 110 views
5

例如,假設我這樣做:散列Python類是個好主意嗎?

>>> 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散列值可能是foobar,或者如果我改變類別,散列值會發生變化。

此行爲是否可靠,或者是否有任何問題?

回答

8

是的,任何不執行__hash__()函數的對象將在散列時返回其ID。從Python Language Reference: Data Model - Basic Customization

用戶定義的類具有__cmp__()__hash__()方法默認;與他們,所有的對象比較不平等(除了與他們自己)和x.__hash__()返回id(x)

但是,如果您希望擁有唯一標識符,請使用id來明確您的意圖。對象的散列應該是其組件散列的組合。請參閱上面的鏈接瞭解更多詳情。

+2

其*元類*沒有__hash __()函數的任何類。 – 2009-08-26 15:30:56

+0

應該指出的是,雖然這是「Python 2.6的新特性」頁面,但這種行爲似乎在python 2.4下適用於我。 – 2009-08-26 15:40:26

+1

@Jason我將參考文獻更改爲一般文檔。 – 2009-08-26 15:41:51

6

類具有__eq____hash__的默認實現,它們分別使用id()進行比較和計算哈希值。也就是說,他們通過身份進行比較。實施__hash__方法的主要原則是,如果兩個對象相互比較相等,則它們也必須具有相同的散列值。散列值可以被看作只是由字典和集合用來更快找到相同對象的優化。因此,如果您更改__eq__以執行其他類型的平等測試,則還必須更改__hash__實現以符合該選擇。

使用標識進行比較的類可以自由地進行變異,並在字典和集合中使用,因爲它們的標識永不改變。實現__eq__的值按值進行比較並允許其值的變異的類不能用於哈希集合。

相關問題