Weekly backup.
This commit is contained in:
89
20220520230639-la_methode_hash.org
Normal file
89
20220520230639-la_methode_hash.org
Normal file
@@ -0,0 +1,89 @@
|
||||
: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]]
|
||||
|
Reference in New Issue
Block a user