Files
org-roamings/20220520230639-la_methode_hash.org
2022-06-04 12:57:39 +02:00

3.3 KiB

La méthode hash

Synthaxe

class.__hash__(self)

La méthode class.__hash__ :

  • Est appelée par la built-in method hash() et pour les opérations sur les membres des hashed collection telles que set, frozenset et dict,
  • Doit retourner un int,
  • Deux objet égaux doivent retourner la même valeur,
  • Si une classe ne définit pas de méthode __eq__, elle ne doit pas définir de méthode __hash__,
  • Si une classe définit une méthode __eq__, mais pas de méthode __hash__, ses instances :

    • Une méthode __hash__ par défaut et retournant None est créée automatiquement,
    • Ne pourront pas être utilisées par les hashable collections,
  • Si une classe définit un objet mutable et définit une méthode __eq__, elle ne doit pas définir de méthode __hash__, l'implémentation des hashables collections nécessitant que la valeur des clés soit immutable,
  • Par défaut, les classes définit par l'utilisateur possèdent les méthodes __eq__ et __hash__ (id(obj) >> 4): tous les objets sont comparés comme non-égaux (sauf chaque objet avec lui-même).

Si a == b, alors hash(a) == hash(b). Si hash(a) == hash(b), alors a pourait être égal à b. Si hash(a) != hash(b), alors a != b.

Exemples

from __future__ import annotations

print(f'{hash(10)=}')
print(f'{hash("abc")=}')

class Dummy:

    def __init__(self, first: str, second: str) -> None:
        self.first = first
        self.second = second
        
class HashableDummy:

    def __init__(self, first: str, second: str) -> None:
        self.first = first
        self.second = second

    def __eq__(self, other: HashableDummy) -> bool:
        return (other is not None
                and isinstance(other, HashableDummy)
                and self.first == other.first
                and self.second == other.second)
    
    def __hash__(self) -> int:
        return hash((self.first, self.second))

    
dummy1, dummy2 = (Dummy("a", "b") for _ in range(2))
print(f'{hash(dummy1)=}')
print(f'{hash(dummy2)=}')
print(f'{dummy1 == dummy2=}')

hashable_dummy1, hashable_dummy2 = (HashableDummy("a", "b") for _ in range(2))
print(f'{hash(hashable_dummy1)=}')
print(f'{hash(hashable_dummy2)=}')
print(f'{repr(hashable_dummy1)=}')
print(f'{repr(hashable_dummy2)=}')
print(f'{hashable_dummy1 == hashable_dummy2=}')
hash(10)=10
hash("abc")=-9106817633146148147
hash(dummy1)=8779192445928
hash(dummy2)=8779192413751
dummy1 == dummy2=False
hash(hashable_dummy1)=2529530665278513875
hash(hashable_dummy2)=2529530665278513875
repr(hashable_dummy1)='<__main__.HashableDummy object at 0x7fc10a69f4c0>'
repr(hashable_dummy2)='<__main__.HashableDummy object at 0x7fc10a51a1c0>'
hashable_dummy1 == hashable_dummy2=True