在Python中,我知道这个值__hash__
给定对象的返回值在该对象的生命周期内应该是相同的。但是,出于好奇,如果不是的话会发生什么?这会造成什么样的破坏?
class BadIdea(object):
def __hash__(self):
return random.randint(0, 10000)
I know __contains__
and __getitem__
会表现得很奇怪,因此听写和集合也会表现得很奇怪。您还可能最终在字典/集中得到“孤立”值。
还会发生什么?它会使解释器崩溃,或者破坏内部结构吗?
你的主要问题确实是字典和集合。如果您将一个对象插入到字典/集合中,并且该对象的哈希值发生变化,那么当您尝试检索该对象时,您最终将在不同的位于字典/集合的底层数组中,因此找不到该对象。这正是为什么 dict 键应该始终不可变的原因。
这是一个小例子:假设我们把o
放入字典中,并且o
的初始哈希值是 3。我们会做这样的事情(稍微简化但明白要点):
Hash table:
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| | | | o | | | | |
+---+---+---+---+---+---+---+---+
^
we put o here, since it hashed to 3
现在我们来说说哈希值o
更改为6
。如果我们想检索o
从字典中,我们将查看现场6
,但是那里什么也没有!这会在查询数据结构时导致漏报。实际上,在字典的情况下,上面数组的每个元素都可以有一个与之关联的“值”,并且在一个位置中可以有多个元素(例如哈希冲突 http://en.wikipedia.org/wiki/Collision_%28computer_science%29)。此外,在决定将元素放置在何处时,我们通常会取数组大小的哈希值模。不过,不管所有这些细节如何,上面的示例仍然准确地传达了当对象的哈希码发生变化时可能出现的问题。
它会使解释器崩溃,或者破坏内部结构吗?
不,这不会发生。当我们说对象的哈希更改是“危险的”时,我们的意思是危险的,因为它本质上违背了哈希的目的,并使代码难以推理(如果不是不可能的话)。我们所说的危险并不是指它可能导致坠机。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)