[Python-3000] PEP 3119 - Introducing Abstract Base Classes
Guido van Rossum
guido at python.org
Sat Apr 28 05:31:09 CEST 2007
On 4/27/07, Adam Olsen <rhamph at gmail.com> wrote:
> On 4/27/07, Thomas Lotze <thomas at thomas-lotze.de> wrote:
> > Guido van Rossum wrote:
> > > Another constraint is that hashable objects, once created, should
> > > never change their value (as compared by ``==``) or their hash value.
> > > If a class cannot guarantee this, it should not derive from
> > > ``Hashable``; if it cannot guarantee this for certain instances only,
> > > ``__hash__`` for those instances should raise a ``TypeError``
> > > exception.
> > Shouldn't this rather be a ValueError since it occurs not because of the
> > type of the object in question, but its value (while in general, there are
> > instances of the same type representing other values which are hashable)?
> >>> hash()
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> TypeError: list objects are unhashable
> Normally the exception is raised because the type is wrong. Requiring
> both TypeError and ValueError be caught just for this special case
> would be confusing. A subclass of both could be created, but that
> seems pedantic with no practical value.
Right. The hash of a tuple, or any other hashable container, is
computed from the hashes of its elements. If any of the elements
happens to be not hashable then it will raise a TypeError and that
will just be passed along by the toplevel hash() call. Turning this
into a ValueError would just be an error-masking accident waiting to
happen. If the sub-hash() call raises another exception, that gets
passed through too.
(At one point in the past I considered making __hash__ a dynamic
instance attribute that would be set to None when the value is
unhashable, and computed dynmically. But computing whether it should
be None is just about as expensive as computing the __hash__ function,
so I abandoned this idea. There's little merit to LBYL hashing
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-3000