小能豆

Python 中的“hashable”是什么意思?

javascript

在 Python 代码中,对象hashable到底是什么意思?


阅读 42

收藏
2024-07-18

共1个答案

小能豆

在 Python 中,对象可哈希意味着对象具有一个固定的哈希值,并且在对象的生命周期内该哈希值不会改变。具体来说:

  1. 可以比较:可哈希对象可以与其他对象进行比较,这使得它们可以用作字典中的键以及集合中的元素。
  2. __hash__() 方法:该方法返回一个整数哈希值,用于在查找字典键时快速比较。
  3. __eq__() 方法:对象必须实现 __eq__() 方法来与其他对象进行相等性比较。
  4. 哈希值是不可变的:对象的哈希值在其生命周期内必须保持不变。

在实际应用中,可哈希对象包括:
- 不可变的内置类型,如 intfloatstrtuple(前提是元组中的所有元素也都是可哈希的)、frozenset 等。
- 用户自定义类的实例默认是可哈希的,除非它们定义了影响其相等性和哈希性的可变字段。

以下是一些说明可哈希性的示例:

  1. 不可变对象:这些对象通常是可哈希的。
    python a = 5 b = "hello" c = (1, 2, 3) d = frozenset([1, 2, 3]) print(hash(a)) # 打印整数 5 的哈希值 print(hash(b)) # 打印字符串 "hello" 的哈希值 print(hash(c)) # 打印元组 (1, 2, 3) 的哈希值 print(hash(d)) # 打印 frozenset {1, 2, 3} 的哈希值

  2. 可变对象:这些对象通常不可哈希。
    python a = [1, 2, 3] b = {1, 2, 3} c = {'key': 'value'} # 以下行会引发 TypeError: unhashable type 错误 # print(hash(a)) # print(hash(b)) # print(hash(c))

  3. 用户自定义类:默认情况下,用户自定义类的实例是可哈希的,除非其 __eq__()__hash__() 方法被不适当地重写。
    ```python
    class MyClass:
    def init(self, value):
    self.value = value

    obj = MyClass(10)
    print(hash(obj)) # 打印对象的哈希值

    如果我们重写 eqhash

    class MyBetterClass:
    def init(self, value):
    self.value = value

    def __eq__(self, other):
        if isinstance(other, MyBetterClass):
            return self.value == other.value
        return False
    
    def __hash__(self):
        return hash(self.value)
    

    obj1 = MyBetterClass(10)
    obj2 = MyBetterClass(10)
    print(obj1 == obj2) # True
    print(hash(obj1), hash(obj2)) # 两者的哈希值相同
    ```

总之,在 Python 中,对象可哈希意味着该对象有一个固定且不可变的哈希值,并且可以与其他对象进行比较,这使得它可以用作字典键或集合元素。

2024-07-18