hash()方法返回一個(gè)對象的哈希值(如果有)。
哈希值只是一些整數(shù),在字典查找過程中用來比較字典鍵。
在內(nèi)部,hash()方法調(diào)用__hash__()對象的方法,該方法默認(rèn)情況下為任何對象設(shè)置。我們稍后再看這個(gè)。
hash()方法的語法為:
hash(object)
hash()方法采用一個(gè)參數(shù):
object -要返回其哈希值的對象(整數(shù),字符串,浮點(diǎn)數(shù))
hash()方法返回一個(gè)對象的哈希值(如果有)。
如果對象具有自定義__hash__()方法,則它將返回值截?cái)酁?strong>Py_ssize_t的大小。
# 整數(shù)的哈希值保持不變 print('181的哈希是:', hash(181)) # 十進(jìn)制哈希 print('181.23的哈希為:',hash(181.23)) # 字符串哈希 print('Python的哈希為:', hash('Python'))
運(yùn)行該程序時(shí),輸出為:
181的哈希是: 181 181.23的哈希為: 579773580 Python的哈希為: 2101984854
hash()方法僅適用于不可變對象,如tuple。
# 元音元組 vowels = ('a', 'e', 'i', 'o', 'u') print('hash是:', hash(vowels))
運(yùn)行該程序時(shí),輸出為:
hash是: -695778075465126279
如上所述,hash()方法在內(nèi)部調(diào)用__hash__()方法。因此,任何對象都可以覆蓋__hash __()以獲得自定義哈希值。
但是對于正確的哈希實(shí)現(xiàn),__ hash __()應(yīng)該始終返回整數(shù)。并且,必須同時(shí)實(shí)現(xiàn)__eq __()和__hash __()方法。
下面是正確的__hash __()重寫的情況。
__eq __() | __hash __() | 描述 |
---|---|---|
已定義(默認(rèn)情況下) | 已定義(默認(rèn)情況下) | 如果保持原樣,所有對象的比較都是不相等的(除了它們自己) |
(如果可變)已定義 | 不應(yīng)該定義 | 實(shí)現(xiàn)hashable集合需要鍵的散列值是不可變的 |
沒有定義 | 不應(yīng)該定義 | 如果未定義__eq __(),則不應(yīng)定義__hash __()。 |
已定義 | 沒有定義 | 類示例將不能用作可哈希收集。 __hash __()隱式設(shè)置為None 如果嘗試檢索哈希,則引發(fā)TypeError異常。 |
已定義 | 保留從父類 | __hash__ = <ParentClass> .__ hash__ |
已定義 | 不散列 | __hash__ =None 如果嘗試檢索哈希,則引發(fā)TypeError異常。 |
class Person: def __init__(self, age, name): self.age = age self.name = name def __eq__(self, other): return self.age == other.age and self.name == other.name def __hash__(self): print('hash是:') return hash((self.age, self.name)) person = Person(23, 'Adam') print(hash(person))
運(yùn)行該程序時(shí),輸出為:
hash是: 3785419240612877014
注意:您不必為哈希實(shí)現(xiàn)__eq __()方法,因?yàn)槟J(rèn)情況下會為所有對象創(chuàng)建哈希。