Instances as dictionary key, __hash__ and __eq__

Jean-Michel Pichavant jeanmichel at sequans.com
Mon Feb 18 20:51:48 CET 2013


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.
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.


More information about the Python-list mailing list