Jean Millikin proposé une solution similaire à ceci:
class A(object):
def __init__(self, a, b, c):
self._a = a
self._b = b
self._c = c
def __eq__(self, othr):
return ((self._a, self._b, self._c) ==
(othr._a, othr._b, othr._c))
def __hash__(self):
return hash((self._a, self._b, self._c))
Le problème avec cette solution est que l' hash(A(a, b, c)) == hash((a, b, c))
. En d'autres termes, la valeur de hachage entre en collision avec celle de la n-uplet de ses principaux membres. Peut-être que cela n'a pas d'importance très souvent dans la pratique?
La documentation Python sur __hash__
suggère de combiner les valeurs de hachage de la sous-composants à l'aide de quelque chose comme XOR, ce qui nous donne ceci:
class B(object):
def __init__(self, a, b, c):
self._a = a
self._b = b
self._c = c
def __eq__(self, othr):
return (isinstance(othr, type(self))
and (self._a, self._b, self._c) ==
(othr._a, othr._b, othr._c))
def __hash__(self):
return (hash(self._a) ^ hash(self._b) ^ hash(self._c) ^
hash((self._a, self._b, self._c)))
Bonus: plus robuste __eq__
jetés là pour faire bonne mesure.
Mise à jour: comme Blckknght points, modification de l'ordre de a, b, et c peuvent causer des problèmes. J'ai ajouté une supplémentaire ^ hash((self._a, self._b, self._c))
de la capture de l'ordre des valeurs hachées. Cette dernière ^ hash(...)
peut être retiré si les valeurs ne peut être modifié (par exemple, si ils ont des types différents et, par conséquent, la valeur de _a
ne sera jamais attribué à l' _b
ou _c
, etc.).