What is the correct way to define __hash__?
Robert Kern
robert.kern at gmail.com
Mon Oct 12 18:29:36 EDT 2009
On 2009-10-12 17:12 PM, Peng Yu wrote:
> On Mon, Oct 12, 2009 at 4:03 PM, Robert Kern<robert.kern at gmail.com> wrote:
>> On 2009-10-12 15:45 PM, Peng Yu wrote:
>>>
>>> Hi,
>>>
>>> I'm wondering what is the general way to define __hash__. I could add
>>> up all the members. But I am wondering if this would cause a
>>> performance issue for certain classes.
>>
>> Unless if you are very familiar with the math of hash functions, I don't
>> recommend that you try to implement one directly. Instead, make a tuple of
>> the hashable content of your class and return the result of calling hash()
>> on that tuple. Be sure to make your equality comparison do the right thing.
>>
>> class A(object):
>> def __init__(self, a, b):
>> self.a = a
>> self.b = b
>>
>> def _key(self):
>> # I include the name of the class so as to differentiate between other
>> # classes that might also have a _key() method. If you have several
>> classes
>> # or subclasses that are allowed to compare equal to each other, use some
>> # other common string here.
>> return (type(self).__name__, a, b)
>>
>> def __hash__(self):
>> return hash(self._key())
>>
>> # Coincidentally, the _key() method can usually be reused for comparisons.
>> # I recommend doing this for the equality comparisons, at least, when you
>> can
>> # because of the requirement that two items that compare equal must have
>> the
>> # same hash value.
>> def __eq__(self, other):
>> return self._key() == other._key()
>>
>> def __ne__(self, other):
>> return not (self == other)
>>
>> ...
>
> Do I need to define other 4 comparison operators besides __eq__ and __ne__?
Yes. There are recipes to fill in the rest if you just provide __eq__ and __lt__:
http://code.activestate.com/recipes/576685/
Or you could continue to use the __cmp__ method, but it will be going away in
Python 3.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
More information about the Python-list
mailing list