Instances as dictionary key, __hash__ and __eq__

Terry Reedy tjreedy at udel.edu
Tue Feb 19 00:39:57 CET 2013


On 2/18/2013 2:51 PM, Jean-Michel Pichavant wrote:
> Greetings,
>
> I opened something like a month ago a thread about hash functions and how I could write classes which instances can be safely used as dictionary keys.
> I though I had it but when I read back my code, I think I wrote yet another bug.
>
> Consider the following simple (buggy) class, python 2.5
>
> class FooSet(object):
>      """Define an algorithm set, containing pdcch/pdsch (or none)."""
>      def __init__(self, pdcch, pdsch):
>          self.pdcch = bool(pdcch)
>          self.pdsch = bool(pdsch)
>      # __hash__ and __eq__ allow to use the object as a dictionary key
>      def __hash__(self):
>          return hash((self.pdcch, self.pdsch))
>      def __eq__(self, other):
>          return hash(self) == hash(other)
>
> Can you confirm that using the hash function for testing equality is a very bad idea ?
>
> One obvious solution would be:
>
> def __eq__(self, other):
>      return self.pdsch = other.pdsch and self.pdcch == other.pdcch
>
> But I was looking for a "standard" solution, that I could use for basically all my container classes
>
> So I came up with these ones:
>
> def __hash__(self):
>      return hash(tuple(vars(self).values()))
> def __eq__(self, other):
>      return vars(self) == vars(other)
>
> But I'm not sure about vars(self).values(), I don't really care about the order of the values, but I need to be sure that for 2 equal dictionaries, they will both return their values in the same order.

No, you cannot depend on that in general even though it may work in 
specific cases.

> And that's the point, I'm not sure at all.
>
> Additionally,  If I'm making things much more complicated than they need to be, let me know.
>
> Cheers,
>
> JM
>
>
> -- IMPORTANT NOTICE:
>
> The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
>


-- 
Terry Jan Reedy




More information about the Python-list mailing list