While the value of the hash function is related, this is not the main factor. Equality is more important here. That is, objects can have the same hash value and not be equal, but equal objects must have the same hash value (although this is not strictly enforced). Otherwise, you will encounter some strange errors when using dict and set .
Since you did not define the __eq__ method on SomeClass , you inherit it on str . Built-in built-in Python is built-in to provide a subclass, so __eq__ returns true if the object would otherwise be equal if it did not have different types. eg. 's' == SomeClass('s') true. Thus, it is right and right that 's' and SomeClass('s') equivalent as keys to a dictionary.
To get the behavior you need, you must override the __eq__ dunder method to take into account the type. However, when you define a user equivalent, python stops giving you the __hash__ dunder automatic method, and you must also override it. But in this case, we can just reuse str.__hash__ .
class SomeClass(str): def __eq__(self, other): return ( type(self) is SomeClass and type(other) is SomeClass and super().__eq__(other) ) __hash__ = str.__hash__ d = {'s': 1} d[SomeClass('s')] = 2 assert len(d) == 2 print(d)
Fingerprints: {'s': 2, 's': 1}
Dunes
source share