📅  最后修改于: 2020-09-20 04:08:24             🧑  作者: Mango
哈希值只是用于在字典查找期间快速比较字典键的整数。
在内部, hash()
方法调用默认为任何对象设置的对象的__hash__()
方法。我们待会再看。
hash()
方法的语法为:
hash(object)
hash()
方法采用一个参数:
hash()
方法返回一个对象的哈希值(如果有)。
如果对象具有自定义__hash__()
方法,则它会将返回值截断为Py_ssize_t
的大小。
# hash for integer unchanged
print('Hash for 181 is:', hash(181))
# hash for decimal
print('Hash for 181.23 is:',hash(181.23))
# hash for string
print('Hash for Python is:', hash('Python'))
输出
Hash for 181 is: 181
Hash for 181.23 is: 530343892119126197
Hash for Python is: 2230730083538390373
hash()
方法仅适用于不可变对象,如元组。
# tuple of vowels
vowels = ('a', 'e', 'i', 'o', 'u')
print('The hash is:', hash(vowels))
输出
The hash is: -695778075465126279
如上所述, hash()
方法在内部调用__hash__()
方法。因此,任何对象都可以覆盖__hash__()
以获得自定义哈希值。
但是对于正确的哈希实现, __hash__()
hash __hash__()
应该始终返回整数。并且,必须同时实现__eq__()
和__hash__()
方法。
以下是正确的__hash__()
覆盖的情况。
__eq__() | __hash__() | Description |
---|---|---|
Defined (by default) | Defined (by default) | If left as is, all objects compare unequal (except themselves) |
(If mutable) Defined | Should not be defined | Implementation of hashable collection requires key’s hash value be immutable |
Not defined | Should not be defined | If __eq__() isn’t defined, __hash__() should not be defined. |
Defined | Not defined | Class instances will not be usable as hashable collection. __hash__() implicity set to None . Raises TypeError exception if tried to retrieve the hash. |
Defined | Retain from Parent | __hash__ = |
Defined | Doesn’t want to hash | __hash__ = None . Raises TypeError exception if tried to retrieve the hash. |
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('The hash is:')
return hash((self.age, self.name))
person = Person(23, 'Adam')
print(hash(person))
输出
The hash is:
3785419240612877014
注意:您不必为哈希实现__eq__()
方法,因为默认情况下会为所有对象创建__eq__()
方法。