python: mes classes comme dict clés. comment?
class A():
def __init__(self, data=''):
self.data = data
def __str__(self):
return str(self.data)
d = {}
elem = A()
d[elem] = 'abc'
elem2 = A()
print d[elem2] # KeyError
# actually elem2! was used not elem
comment puis-je mettre en œuvre cette sans erreur?
EDIT:
FFFUUU, l'erreur était:
J'ai essayé d'obtenir d[elem2]
(pas elem
) avec une autre instance d'UNE (), MAIS avec le même contenu. (honte sur moi)
Encore.. comment puis-je faire cela? redéfinir __hash__
?
- Quelle est l'erreur (message)? Et faut-il vraiment se produire uniquement lorsque vous accédez à un élément, au lieu de le définir? Avez-vous vraiment (comme dans l'exemple) utiliser la même instance dans les deux lignes, ou est-ce
d[A()] = ...; print d[A()]
? - Oui, seulement lors de la prise, pas de réglage. Modifié: KeyError.
- Vous devrez nous en dire plus sur la classe
A
. Avez-vous d'écraser les méthodes spéciales? Lors de l'affichage de messages d'erreur, merci de donner le complet message d'erreur, y compris le traceback. - défini init et str comme je l'ai écrit ci-dessus
- La mise à jour du code s'exécute sans erreur pour moi.
- désolé tout le monde, édité à la question
Vous devez vous connecter pour publier un commentaire.
La réponse est oui, vous devez redéfinir
__hash__()
:Comme expliqué dans un autre commentaire par défaut de mise en œuvre de
__hash__
est tout simple identité, donc si vous voulez le rendre plus sophistiqué, vous devez définir explicitement.__eq__
, ou des choses étranges se produisent (au moins en Python 2.7), j'ai testé pour vous...Ce que vous avez fait devrait fonctionner, aussi longtemps que vous ne pas écraser la
__hash__()
et__eq__()
méthodes. Il va utiliser l'identité de l'objet que l'égalité. Si vous souhaitez une autre notion de l'égalité, vous pouvez remplacer la__hash__()
et__eq__()
méthodes de votre classe.ssn
attribut est la même chose, alors ils sont égaux, même si leurs noms sont différents (puisque les gens peuvent changer de nom). Vous serait alors écrire__eq__()
de comparer seulementself.ssn
et__hash__()
de retourhash(self.ssn)
. Un certain nombre de domaines peuvent être envisagées, en fonction de ce que les objets représentent.