What is the correct way to define __hash__?
Chris Rebert
clp2 at rebertia.com
Mon Oct 12 18:20:43 EDT 2009
On Mon, Oct 12, 2009 at 3:12 PM, Peng Yu <pengyu.ut at gmail.com> 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__?
No; dictionaries are unordered and thus don't utilize the non-equality
comparison operators.
Cheers,
Chris
--
http://blog.rebertia.com
More information about the Python-list
mailing list