这是我的代码:
class Hero:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return self.name + str(self.age)
def __hash__(self):
print(hash(str(self)))
return hash(str(self))
heroes = set()
heroes.add(Hero('Zina Portnova', 16)) # gets hash -8926039986155829407
print(len(heroes)) # gets 1
heroes.add(Hero('Lara Miheenko', 17)) # gets hash -2822451113328084695
print(len(heroes)) # gets 2
heroes.add(Hero('Zina Portnova', 16)) # gets hash -8926039986155829407
print(len(heroes)) # gets 3! WHY?
为什么会发生这种情况?
第一个和第三个对象具有相同的内容和相同的散列,但len()
告诉大约3个唯一对象?
答案 0 :(得分:54)
您还需要以__hash__()
的兼容方式定义__eq__()
- 否则,相等性将基于对象标识。
在Python 2上,建议您定义__ne__
以使!=
与==
保持一致。在Python 3上,默认的__ne__
实现将委托给__eq__
。
答案 1 :(得分:15)
以下是整个代码:
class Hero:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return self.name + str(self.age)
def __hash__(self):
print(hash(str(self)))
return hash(str(self))
def __eq__(self,other):
return self.name == other.name and self.age== other.age
heroes = set()
heroes.add(Hero('Zina Portnova', 16)) # gets hash -8926039986155829407
print(len(heroes)) # gets 1
heroes.add(Hero('Lara Miheenko', 17)) # gets hash -2822451113328084695
print(len(heroes)) # gets 2
heroes.add(Hero('Zina Portnova', 16)) # gets hash -8926039986155829407
print(len(heroes)) # gets 2
该函数识别__eq__
,因此len为2。
答案 2 :(得分:8)
The Python documentation可能会有所帮助:
如果某个类未定义
__cmp__()
或__eq__()
方法,则不应定义__hash__()
操作;