【发布时间】:2021-04-24 20:23:36
【问题描述】:
首先,在为公共项目和/或论坛做贡献方面,我是一个完全的新手,我知道这个问题相对“基于意见”,但我不知道我应该在哪里发布这个问题,我觉得它可能对其他人有用。
在为 python 3.7.3 编写其他一些代码的测试时,我遇到了一种情况,计数器的键既不在计数器中,也不在键中。
以下代码重现并指向问题:
class MyHashable(object):
def __init__(self,label,key='something'):
self.label = label
self.key = key
def __hash__(self):
return hash((self.label,self.key))
def __eq__(self,other):
return (self.label,self.key) == (other.label,other.key)
TestDict = dict()
A = MyHashable('label1')
B = MyHashable('label2')
B.key = 'something else' # Changing the hash of B
TestDict[A] = 12
TestDict[B] = 'ASDR'
A.key = 24 # Changing the hash of A
Case1 = A in TestDict # False
Case2 = B in TestDict # True
Case3 = A in TestDict.keys() # False
Case4 = B in TestDict.keys() # True
Case5 = A in tuple(TestDict.keys()) # True
Case6 = B in tuple(TestDict.keys()) # True
我认为 Case3 不是 Case1 的根本原因,因为 Case3 在 python 2.7.17 中评估为 True。 (请记住,python2.7 的案例 5 和 6 应该是“==”而不是“in”语句)。我猜测根本原因与std库的底层c代码有关,但这无关紧要,除非标题问题的答案是肯定的。
我相信这个错误显然是我修改影响散列调用的属性在将它包含在字典中但我觉得有必要在某个地方指出它。我认为这绝对是有用的,它出现在某个地方,这样遇到这种情况的人可能会相对较快地找到它。此外,我认为这是一个很好的例子,说明如何不创建可哈希类,或者至少是在 python 中错误使用可哈希类的好例子。
是的,我知道字典中的这种情况不太可能发生,而且闻起来完全像是程序员的错。但在其他可映射对象(例如 collections.Counter)中,程序员可能只对计数内容感兴趣。 The Mapping Types documentation of python 3.9.1 状态:
映射对象将可散列值映射到任意对象
因此,程序员将使对象的类(程序员想要计算的)可散列(在本例中不超过 4 行),然后继续处理更重要的问题。最后,程序员会遇到一个看起来很奇怪的错误,即添加到计数器中的项目不在计数器中in。
切入正题。这种行为是 bug 吗?应该将其作为错误提交给 python 核心开发人员还是其他地方?
*编辑:修复示例代码中的错误
【问题讨论】: