On Thu, Sep 1, 2011 at 18:08, Steven D'Aprano <st...@pearwood.info> wrote: > 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, Do you have an actual example of an actual object for which "my" is_hashable(object) function would return the wrong answer? >>> def is_hashable(object): ... try: ... hash(object) ... except TypeError: ... return False ... return True ... >>> is_hashable((1, 2, [3])) False >>> Is that one? Dick _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor