• 17 Posts
  • 29 Comments
Joined 1 year ago
cake
Cake day: August 30th, 2025

help-circle

  • Yes indeed, the ‘int’ objects are stored and searched in the set based on their value, and the ‘Value’ objects are stored/searched based on their identity unless you define the above __eq__ and __hash__ methods which cause them to be stored/searched based on value too. This is a Python design decision and that’s the point of this exercise. The fact that ‘int’ is an immutable type and we are replacing isn’t relevant. Try replacing/reassigning the ‘Value’ objects after added __eq__ and __hash__, and you get the same result as for ‘int’. So the thing that really matters is how __eq__ and __hash__ are defined, and the default for a user-defined class is as stated in the “Explanation:” above.

    Maybe I should also show a class with __eq__ and __hash__ defined based on value, but then it gets a bit long. I’ll have to rethink this exercises so that the point comes across better as it now seems to confuse a lot of people based on the down-votes. Thanks for feedback anyway.


  • Sure, but a lot of people incorrectly think the __eq__ and __hash__ are defined based on value not identity, as they are for many other types say float, str, or tuple. But for a class the default __eq__ method is x is y instead of x == y and also __hash__ is based on identity.

    Others assume that if you don’t define __hash__ for a class, that it doesn’t exists (like for list, set, or dict) so that a “TypeError: unhashable type: ‘Value’” exception is raised.

    I thought it was an interesting exercise to share, but maybe too simple for this audience, or people are just not aware of the basic steps that happen when adding and searching values in a set/dict. Try the same with type int:

    v1 = 1001
    v2 = 1002
    myset = {v1}
    print(v1 in myset, end=' ')
    v2 = 1001
    print(v2 in myset, end=' ')
    v1 = 1002
    print(v1 in myset, end=' ')
    

    and you see a different output. To do the same with the Value class add methods:

    def __eq__(self, other):
        return self.value == other.value
    
    def __hash__(self):
        return hash(self.value)
    
































  • Thanks for your feedback, much appriciated.

    I agree that an exercise14.rst would be nice, but to save time I’ve let the code speak for itself now together with the visualizaion. I’ll probably revisit and better document the exercises later.

    At the Explanation link I try to give a general explanation about Pyrhon mutability (and copy later on), I agree some readers might find it hard to relate that to a specific exercise, but I don’t want to write a specific explanation for each exercise.