Hashability of classes, old and new

François Pinard pinard at iro.umontreal.ca
Mon Feb 16 09:15:55 EST 2004


Hi, people.  I observe that there is a difference in hashability between
old-style and new-style instances, when they are comparable.  I wonder
what I meaning I should make out of this. Maybe the simplest is to first
show an example:

---------------------------------------------------------------------->
Python 2.3.3 (#1, Jan 24 2004, 09:01:30) 
[GCC 3.3 20030226 (prerelease) (SuSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class C:
...   __metaclass__ = type
...   def __cmp__(a, b):
...     print 'C', a, b
...     return 0
... 
>>> class D:
...   import types
...   __metaclass__ = types.ClassType
...   def __cmp__(a, b):
...     print 'D', a, b
...     return 0
... 
>>> c = C()
>>> d = D()
>>> hash(C)
136172876
>>> hash(D)
1076805372
>>> hash(c)
1076846924
>>> hash(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: unhashable instance
----------------------------------------------------------------------<

As you see, `C' is new-style, `D' is old-style.  (I could have written
declarations more simply, if __metaclass__ was not preset to type within
my `.pythonrc' -- in any case, the above writing is very explicit. :-)

Is there a change in semantics in this area?  For new-style, I have:

---------------------------------------------------------------------->
>>> c1 = C()
>>> c2 = C()
>>> z = {}
>>> z[c1] = 101
>>> z[c2] = 102
>>> c1 == c2
C <__main__.C object at 0x402f650c> <__main__.C object at 0x402f64ec>
True
>>> z[c1]
101
>>> z[c2]
102
----------------------------------------------------------------------<

So, despite c1 equals c2, they create two different entries in a
dictionary.  I thought that this is such an inconsistency that was the
reason behind requiring an explicit `__hash__' for old-style classes.
So, it seems I was not thinking right, there is something which escapes
my understanding.  Would some kind soul help mine? :-)

-- 
François Pinard   http://www.iro.umontreal.ca/~pinard




More information about the Python-list mailing list