Đây là mã của tôi:Làm thế nào để tạo một đối tượng có thể băm đúng?
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?
Tại sao điều này xảy ra?
Đối tượng thứ nhất và thứ 3 có cùng nội dung và cùng một mã băm nhưng len()
cho biết khoảng 3 đối tượng duy nhất?
Không chắc, nhưng có lẽ bạn cần '__eq__' hoặc '__cmp__' : http://docs.python.org/glossary.html#term-hashable – nhahtdh
Điều đó sang một bên, đây không phải là hàm băm tốt nhất (vì bạn không băm một chuỗi chung, một trong các thành phần chuỗi có entropy thấp hơn nhiều bởi vì nó được biết là bao gồm các chữ số). Đối với một sửa chữa tầm thường nhưng khá hiệu quả, lấy giá trị băm của các đối tượng riêng biệt và xor chúng. Để có thêm ma thuật, hãy thêm chúng theo thang số nguyên tố. –
@KonradRudolph: Có một giả định ngụ ý trong nhận xét của bạn - đặc biệt là một băm "tốt" là cần thiết cho các thiết lập để thực hiện tốt. Đây không phải là trường hợp với việc thực thi 'set' của Python; xem [bình luận này từ các nguồn Python] (http://hg.python.org/cpython/file/26e2ee402a0b/Objects/dictobject.c#l113) để được giải thích thêm. –