Why are tuples immutable?

Nick Coghlan ncoghlan at iinet.net.au
Sat Dec 18 06:51:54 CET 2004


Jeff Shannon wrote:
> That does put a kink in my argument that Python is simply refusing to 
> guess in the face of ambiguity.  I'm still convinced that disallowing 
> lists as dict keys is a good thing, but it leaves me unable to explain 
> why __hash__()-less user-defined classes (which are mutable almost by 
> definition) are allowed.

Because the default definition of equality is *also* based on object id. Since 
the hash and equality are based on the same thing, such classes can be safely 
used as dictionary keys.

As soon as you define __cmp__ or __eq__ Python does *not* supply a default 
implementation of __hash__ - since it can no longer assume that an identity 
based hash will give a correct answer.

Py> class Hashable: pass
...
Py> hash(Hashable())
10331280
Py> d = {Hashable(): "Hi"}
Py> d
{<__main__.Hashable instance at 0x009DA490>: 'Hi'}
Py> class NotHashable:
...   def __cmp__(self, other):
...     return 0
...
Py> hash(NotHashable())
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
TypeError: unhashable instance
Py> d = {NotHashable(): "Hi"}
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
TypeError: unhashable instance


Although, it looks like new-style classes currently don't apply this rule - you 
get the default hash implementation from object no matter what:

Py> class NotHashable(object):
...   def __cmp__(self, other):
...     return 0
...
Py> hash(NotHashable())
10297264
Py> d = {NotHashable(): "Hi"}
Py> d
{<__main__.NotHashable object at 0x009D1FF0>: 'Hi'}

That may be a bug rather than a feature :)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at email.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://boredomandlaziness.skystorm.net



More information about the Python-list mailing list