我正在一个对象中实现哈希函数,并且我使用用户名哈希值作为该对象的哈希值,即:
class DiscordUser:
def __init__(self, username):
self.username = username
def __hash__(self):
return hash(self.username)
将此类对象添加到哈希集并将它们与作为构造函数输入的完全相同的用户名进行比较时,就会出现问题,即:
user = DiscordUser("Username#123")
if user in users_set:
# user is already in my users_set, such condition is NEVER MET, dont understand why
else:
# add user to users_set, this condition is met ALWAYS
users_set.add(user)
为什么哈希函数无法正常工作,或者我在这里做错了什么?
哈希函数正常工作,
set
成员资格使用__hash__()
,但如果两个对象具有相同的哈希,set
将使用__eq__()
方法来确定它们是否相等。最终,set
保证没有两个元素相等,而不是没有两个元素具有相等的哈希值。哈希值被用作第一遍,因为它的计算成本通常比相等性要低。
无法保证任何两个具有相同哈希值的对象实际上是相等的。考虑一下您的
self.name
中的 DiscordUser
有无限个值。 Python 使用 siphash 对 str
值进行哈希处理。 Siphash 的范围是有限的,因此碰撞肯定是可能的。
使用可变值作为
hash()
的输入时要小心。对象的哈希值在其生命周期内应该是相同的。
看看这个 answer,了解有关 Python 中的
set
、哈希和相等测试的一些不错的信息。
编辑:自 3.4 起,Python 使用 siphash 表示
str
值