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   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---------------------------------------------------------------
            http://boredomandlaziness.skystorm.net
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to