On Tue, Sep 14, 2021 at 11:30 PM <johnmelendow...@gmail.com> wrote:
>
> I think I implemented __eq__ but not __hash__ and it broke the golden rule of 
> x == y => x is y i,.e. hash(x) == hash(y)
>

Not sure what you're referring to there. The rule regarding hashes is
that if x == y, then hash(x) == hash(y). Identity doesn't come into
it, other than in the trivial sense that, for most classes, hash(x) ==
hash(x) (in other words, the hash is stable), and x == x, which
complies with the rule. But if x != x (eg with float("nan")), there's
no problem.

Incidentally, I don't think it's documented, but an object's hash
should never change. Otherwise, you can get bizarre behaviours:

>>> class X:
...     def __init__(self, value): self.thing = value
...     def __eq__(self, other): return self.thing == other.thing
...     def __hash__(self): return hash(self.thing)
...
>>> stuff = {X(5): "hello", X(7): "world"}
>>> stuff[X(5)]
'hello'

Well and good. But if we mutate the key...

>>> list(stuff)[0].thing = 2
>>> for key in stuff:
...     print(key, stuff[key])
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyError: <__main__.X object at 0x7f1420409180>
>>>

... we can iterate over the keys in the dictionary, use that exact
object to subscript the dictionary, and it isn't found. That key/value
pair has been placed in the bucket for 5, and won't be found in 2's
bucket.

If equality can change, __hash__ should be omitted.

ChrisA
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/PYQRBNKJDRIYXM3DLVX7MZDYH3O3K5SU/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to