90 lines
3.3 KiB
Org Mode
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]]
|
|
|