<div dir="ltr"><br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div><div class="Wj3C7c"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
It's probably a good idea to implement __hash__ for objects that<br>
implement comparisons, but it won't always work and it is certainly<br>
not needed, unless you intend to use them as dictionary keys.<br>
<br>
<br>
</blockquote>
<br>
<br></div></div>
So you're suggesting that we document something like.<br>
<br>
Classes that represent mutable values and define equality methods are free to define __hash__ so long as you don't mind them being used incorrectly if treated as dictionary keys...<br>
<br>
Technically true, but not very helpful in my opinion... :-)</blockquote><div><br>No, I think he was suggesting we document that if a class overrides __eq__, it's a good idea to also implement __hash__, so it can be used as a dictionary key.<br>
<br>However I have issues with this. First, he said:<br><br>"It's probably a good idea to implement __hash__ for objects that<br>
implement comparisons, but it won't always work and it is certainly<br>
not needed, unless you intend to use them as dictionary keys." <br><br>You can't say "certainly not needed unless you intend to use them as dictionary keys", since if you are defining an object, you never know when someone else will want to use them as a dict key (or in a set, mind!) So *if possible*, it is a good idea to implement __hash__ if you are implementing __eq__.<br>
<br>But also, it needs to be very clear that if you *should not* implement __hash__ on a mutable object -- and it already is. So basically the docs should suggest that it is a good idea to implement __hash__ if you are implementing __eq__ on an immutable object.<br>
<br>HOWEVER,<br><br>There are two contradictory pieces of information in the docs.<br><br>a) "if it defines
<a title="object.__cmp__" class="reference" href="http://docs.python.org/dev/reference/datamodel.html#object.__cmp__"><tt class="xref docutils literal"><span class="pre">__cmp__()</span></tt></a> or <a title="object.__eq__" class="reference" href="http://docs.python.org/dev/reference/datamodel.html#object.__eq__"><tt class="xref docutils literal"><span class="pre">__eq__()</span></tt></a> but not <a title="object.__hash__" class="reference" href="http://docs.python.org/dev/reference/datamodel.html#object.__hash__"><tt class="xref docutils literal"><span class="pre">__hash__()</span></tt></a>, its instances
will not be usable as dictionary keys."<br>versus<br>b) "User-defined classes have <a title="object.__cmp__" class="reference" href="http://docs.python.org/dev/3.0/reference/datamodel.html#object.__cmp__"><tt class="xref docutils literal"><span class="pre">__cmp__()</span></tt></a> and <a title="object.__hash__" class="reference" href="http://docs.python.org/dev/3.0/reference/datamodel.html#object.__hash__"><tt class="xref docutils literal"><span class="pre">__hash__()</span></tt></a> methods
by default; with them, all objects compare unequal and <tt class="docutils literal"><span class="pre">x.__hash__()</span></tt>
returns <tt class="docutils literal"><span class="pre">id(x)</span></tt>."<br><br>Note that these statements are somewhat contradictory: if a class has a __hash__ method by default (as b suggests), then it isn't possible to "not have a __hash__" (as suggested by a).<br>
<br>In Python 2, statement (a) is true for old-style classes only, while statement (b) is true for new style classes only. This distinction needs to be made. (For old-style classes, it isn't the case that it has a __hash__ method by default - rather that the hash() function knows how to deal with objects without a __hash__ method, by calling id()).<br>
<br>In Python 3, statement (a) is true always, while statement (b) is not (in fact just the same as old-style classes are in Python 2). So the Python 3 docs can get away with being simpler (without having to handle that weird case).<br>
<br>I just saw Marc-Andre's new email come in; I'll look at that now.<br><br>Matt<br></div></div></div>