目的是通过列表切片和比较来预测结果在具有用户定义对象的更复杂的项目中。我以为效果不是覆盖hash函数的目的是影响那些结果,但是并不能在这里和在这里做的还不清楚如何做到。如果eq被覆盖,则被覆盖hash函数必须存在,但是它可以返回'rhubarb'并且仍然不影响结果在这里。由于比较是通过eq完成的,因此hash函数,以什么方式实际使用它的返回值?
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
由于比较是由eq完成的,所以哈希函数的目的是什么?实际使用它的返回方式是什么?
这是一个基本问题why do we need hashing in the first place。
学习how are dicts and sets (hash tables) implemented将帮助您理解哈希
这里[how to implement __hash__
the right way for a custom class