[Tutor] Is there a test for hashability?

James Reynolds eire1130 at gmail.com
Thu Sep 1 16:51:47 CEST 2011


On Thu, Sep 1, 2011 at 10:32 AM, Richard D. Moores <rdmoores at gmail.com>wrote:

> The glossary defines "hashable" as:
>
> hashable
> An object is hashable if it has a hash value which never changes
> during its lifetime (it needs a __hash__() method), and can be
> compared to other objects (it needs an __eq__() method). Hashable
> objects which compare equal must have the same hash value.
>
> Hashability makes an object usable as a dictionary key and a set
> member, because these data structures use the hash value internally.
>
>
> All of Python’s immutable built-in objects are hashable, while no
> mutable containers (such as lists or dictionaries) are. Objects which
> are instances of user-defined classes are hashable by default; they
> all compare unequal, and their hash value is their id().
>
> 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?
>
> Thanks,
>
> Dick Moores
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>



To test for a method within any object you can just go like this:

>>> a = ()
>>> type(a)
<type 'tuple'>
>>> if '__hash__' in dir(a): print True
True
>>> if '__eq__' in dir(a): print True
True
>>>

But, I think the method you are approaching it from will only test for
hashability. For example, you could do this:

>>> a = []
>>> type(a)
<type 'list'>
>>> if '__hash__' in dir(a): print True
True
>>> if '__eq__' in dir(a): print True
True
>>>

and then do this:

>>> b = []
>>> c = {b:1}

Traceback (most recent call last):
  File "<pyshell#36>", line 1, in <module>
    c = {b:1}
TypeError: unhashable type: 'list'

here is the dir for a list (not hashable):

>>> dir(b)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
'__delslice__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__',
'__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__',
'__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__',
'__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append',
'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

here is the dir for a tuple (hashable):

>>> dir(())
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
'__getslice__', '__gt__', '__hash__', '__init__', '__iter__', '__le__',
'__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', 'count', 'index']

What I would probably do though is use the built in method hash

so you could do something like this:

>>> a = 'a'
>>> b = ()
>>> c = []
>>> print type(a), type(b), type(c)
<type 'str'> <type 'tuple'> <type 'list'>
>>> print hash(a)
-468864544
>>> print hash(b)
3527539
>>> print hash(c)

Traceback (most recent call last):
  File "<pyshell#48>", line 1, in <module>
    print hash(c)
TypeError: unhashable type: 'list'
>>>


You can then use try, except to catch it on an as needed basis.

Not sure if this answers the question you are asking though.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20110901/12029ba9/attachment.html>


More information about the Tutor mailing list