[Tutor] Is there a test for hashability?

Steven D'Aprano steve at pearwood.info
Fri Sep 2 03:08:41 CEST 2011


Richard D. Moores wrote:
> I'm trying to write a general test for hashability. How can I test if
> an object has both a  __hash__() method and an __eq__() method?


Just because an object has a __hash__ method doesn't mean it is 
guaranteed to be hashable. The method might (deliberately, or 
accidentally) fail and raise an exception.

 >>> t = (1, 2, 3)
 >>> t.__hash__
<method-wrapper '__hash__' of tuple object at 0xb7f09fcc>
 >>> hash(t)
-378539185

But:

 >>> t = (1, 2, [3])
 >>> t.__hash__
<method-wrapper '__hash__' of tuple object at 0xb7f0c6e4>
 >>> hash(t)
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable


The only effective way to find out if an object is hashable is to try it 
and see.

Even more effective is to avoid trying to find out whether it is 
hashable, and just use it, as required, and deal with the error if it 
isn't. This is the "Easy to get forgiveness than to ask permission" 
model of error handling, as opposed to "Look before you leap".

For various reasons, LBYL can be risky... like in Quantum Mechanics, the 
very act of *looking* at an object might change its behaviour. (Methods 
can have side-effects.) So, even if is_hashable(obj) returns True, you 
can't *quite* be 100% certain that mydict[obj] will succeed until you 
try it.


-- 
Steven


More information about the Tutor mailing list