<br><br><div class="gmail_quote">On Thu, Sep 1, 2011 at 10:32 AM, Richard D. Moores <span dir="ltr"><<a href="mailto:rdmoores@gmail.com">rdmoores@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
The glossary defines "hashable" as:<br>
<br>
hashable<br>
An object is hashable if it has a hash value which never changes<br>
during its lifetime (it needs a __hash__() method), and can be<br>
compared to other objects (it needs an __eq__() method). Hashable<br>
objects which compare equal must have the same hash value.<br>
<br>
Hashability makes an object usable as a dictionary key and a set<br>
member, because these data structures use the hash value internally.<br>
<br>
<br>
All of Python’s immutable built-in objects are hashable, while no<br>
mutable containers (such as lists or dictionaries) are. Objects which<br>
are instances of user-defined classes are hashable by default; they<br>
all compare unequal, and their hash value is their id().<br>
<br>
I'm trying to write a general test for hashability. How can I test if<br>
an object has both a __hash__() method and an __eq__() method?<br>
<br>
Thanks,<br>
<br>
Dick Moores<br>
_______________________________________________<br>
Tutor maillist - <a href="mailto:Tutor@python.org">Tutor@python.org</a><br>
To unsubscribe or change subscription options:<br>
<a href="http://mail.python.org/mailman/listinfo/tutor" target="_blank">http://mail.python.org/mailman/listinfo/tutor</a><br>
</blockquote></div><br><div><br></div><div><br></div><div>To test for a method within any object you can just go like this:</div><div><br></div><div><div>>>> a = ()</div><div>>>> type(a)</div><div><type 'tuple'></div>
<div>>>> if '__hash__' in dir(a): print True</div><div>True</div></div><div><div>>>> if '__eq__' in dir(a): print True</div><div>True</div><div>>>> </div></div><div><br></div><div>
But, I think the method you are approaching it from will only test for hashability. For example, you could do this:</div><div><br></div><div><div><div>>>> a = []</div><div>>>> type(a)</div><div><type 'list'></div>
<div>>>> if '__hash__' in dir(a): print True</div><div>True</div></div><div><div>>>> if '__eq__' in dir(a): print True</div><div>True</div><div>>>> </div></div></div><div><br></div>
<div>and then do this:</div><div><br></div><div><div>>>> b = []</div><div>>>> c = {b:1}</div><div><br></div><div>Traceback (most recent call last):</div><div> File "<pyshell#36>", line 1, in <module></div>
<div> c = {b:1}</div><div>TypeError: unhashable type: 'list'</div></div><div><br></div><div>here is the dir for a list (not hashable):</div><div><br></div><div><div>>>> dir(b)</div><div>['__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']</div>
</div><div><br></div><div>here is the dir for a tuple (hashable):</div><div><br></div><div><div>>>> dir(())</div><div>['__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']</div>
</div><div><br></div><div>What I would probably do though is use the built in method hash</div><div><br></div><div>so you could do something like this:</div><div><br></div><div><div>>>> a = 'a'</div><div>
>>> b = ()</div><div>>>> c = []</div><div>>>> print type(a), type(b), type(c)</div><div><type 'str'> <type 'tuple'> <type 'list'></div><div>>>> print hash(a)</div>
<div>-468864544</div><div>>>> print hash(b)</div><div>3527539</div><div>>>> print hash(c)</div><div><br></div><div>Traceback (most recent call last):</div><div> File "<pyshell#48>", line 1, in <module></div>
<div> print hash(c)</div><div>TypeError: unhashable type: 'list'</div><div>>>> </div></div><div><br></div><div><br></div><div>You can then use try, except to catch it on an as needed basis.</div><div><br>
</div><div>Not sure if this answers the question you are asking though.</div>