Purpose of this was to predict outcomes from list slicing and comparisons in a more complicated project with user defined objects. I thought that the effect if not the purpose of overriding the hash function was to influence those outcomes but it does not do that here and as done here it is not clear how it could. If eq is overriden then the overriden hash function has to be there but it can return 'rhubarb' and still not affect the outcomes here. Since the comparison is being done by eq what is the purpose of the hash function and in what way is its return actually used?
class Myobj:
def __init__(self,name,suffix='xx', age=21):
self.name=name
self.age=age
self.suffix=suffix
self.handle=self.name +self.suffix
def __eq__(self,other):
return self.name==other.name and self.age==other.age #returns bool
def __hash__(self):
return hash(self.suffix) #or any or all of name,age,suffix or anything - no difference
def __repr__(self):
return self.name
def __str__(self):
return f'{self.handle}'
a=Myobj('one')
b=Myobj('two',suffix='yy')
c=Myobj('three')
d=Myobj('four')
e=Myobj('one',age=10)
g=Myobj('one',suffix='yy')
#with __eq__ and __hash__ overriden
print([a,b,c,d,e]) #[one, two, three, four, one]
print(a,b) #onexx twoyy
print()
print(f' a=c? {a==c}') #returns False, names are not=
print(f' a=e? {a==e}') #returns False, ages are not=
print(f' a=g? {a==g}') #returns True, names=, ages= but self.suffix!=other.suffix
print(hash(a),hash(g)) #791158507 -1150071058
print(hash(a.suffix)) #791158507
print(hash('xx')) #791158507
print(Myobj.__hash__(a)) #791158507
print(set([a,b,c,d,e,g])) #{one, one, two, one, four, three}
# now with default hash and eq dunders
# print([a,b,c,d,e]) #[one, two, three, four, one]
# print(a,b) #onexx twoyy
# print()
# print(f' a=c? {a==c}') #returns False
# print(f' a=e? {a==e}') #returns False
# print(f' a=g? {a==g}') #returns False
# print(hash(a),hash(g)) #1463830 1463857
# print(hash(a.suffix)) #-819204916
# print(hash('xx')) #-819204916
# print(Myobj.__hash__(a)) #1463830