【发布时间】:2020-08-17 22:45:18
【问题描述】:
这样做的目的是预测列表切片和比较的结果 在具有用户定义对象的更复杂的项目中。我以为效果如果不是 覆盖 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
【问题讨论】: