【发布时间】:2021-10-10 14:11:34
【问题描述】:
这是我的课程,我故意让它发生哈希冲突:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f'({self.name} - {self.age})'
def __eq__(self, other):
print('__eq__ called for', self)
return False
def __hash__(self):
print('__hash__ called for', self)
return 1
obj1 = Person('Soroush', 25)
obj2 = Person('John', 23)
print('\n--------Creation of set---------\n')
s = {obj1, obj2}
print(s)
print('\n-------Membership testing-------\n')
print(obj2 in s)
输出:
--------Creation of set---------
__hash__ called for (Soroush - 25)
__hash__ called for (John - 23)
__eq__ called for (Soroush - 25)
{(Soroush - 25), (John - 23)}
-------Membership testing-------
__hash__ called for (John - 23)
__eq__ called for (Soroush - 25)
True
*我的问题来自输出的“成员资格测试”部分:
在obj2 in s语句中,python首先计算obj2的hash(好,第一行输出),然后因为obj1和obj2有相同的hash,python会去看看他们是不是相同的项目与否,obj1 的 __eq__ 被调用(输出的第二行)。他们不是 !我有意为所有实例返回False。所以 python 继续检查探测序列。这里的哈希值再次相等!为什么 python 不调用 obj2 的 __eq__ 来查看这些项目是否相等?
我希望在第三行看到__eq__ called for (John - 23),而且因为obj2 不等于obj2,所以输出的最后一行应该是False。喜欢:
print(obj2 == obj2)
输出:
__eq__ called for (John - 23)
False
那么,为什么没有__eq__ called for (John - 23),为什么没有True?它们不是同一个项目(同样的事情发生在一秒钟前obj1)。
【问题讨论】:
-
也许因为
obj2 is obj2没有调用__eq__方法? -
@qouify 所以你的意思是源代码中有一个身份检查语句,它首先查看ID是否相等?
-
@SorousHBakhtiary 取决于您对“正常”的含义。我会说这很不寻常,但那是因为你的对象。通常,对象等于它们自己。可能最著名的反例是
float('nan')。