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

90 lines
3.3 KiB
Org Mode

:PROPERTIES:
:ID: d1877b3b-3fe5-43d5-9be2-afb5ffe6b918
:mtime: 20220522095337
:ctime: 20220520230639
:END:
#+title: La méthode __hash__
* Synthaxe
#+BEGIN_SRC python
class.__hash__(self)
#+END_SRC
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
#+BEGIN_SRC python :results output
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=}')
#+END_SRC
#+RESULTS:
: 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
* Références
* [[https://docs.python.org/3/reference/datamodel.html#object.__hash__][object.__hash__ - Docs Python]]
* [[https://zestedesavoir.com/tutoriels/954/notions-de-python-avancees/1-starters/3-mutables-hashables/#3-3-hashables][Hashables - Zeste de savoir]]
* [[https://eng.lyft.com/hashing-and-equality-in-python-2ea8c738fb9d][Hashing and equality in Python - Roy Williams]]