What is the correct way to define __hash__?

Peng Yu pengyu.ut at gmail.com
Tue Oct 13 00:12:46 CEST 2009


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__?



More information about the Python-list mailing list