<p>将始终调用<code>__hash__</code>;<code>__eq__</code>如果对象确实在字典中,或者如果字典中有另一个具有相同哈希的对象,则将调用<code>__eq__</code>。散列值用于缩小可能键的选择范围。这些键按哈希值分组到“bucket”中,但是对于lookup,Python仍然必须检查bucket中的每个键是否与lookup key相等。见<a href="http://wiki.python.org/moin/DictionaryKeys">http://wiki.python.org/moin/DictionaryKeys</a>。看看这些例子:</p>
<pre><code>>>> class Foo(object):
... def __init__(self, x):
... self.x = x
...
... def __hash__(self):
... print "Hash"
... return hash(self.x)
...
... def __eq__(self, other):
... print "Eq"
... return self.x == other.x
>>> Foo(1) in d
Hash
Eq
10: True
>>> Foo(2) in d
Hash
Eq
11: True
>>> Foo(3) in d
Hash
Eq
12: True
>>> Foo(4) in d
Hash
13: False
</code></pre>
<p>在该示例中,您可以看到始终调用<code>__hash__</code>。^当对象在dict中时,每次查找都会调用一次{<cd2>},因为它们都有不同的哈希值,因此一次相等性检查就足以验证具有该哈希值的对象确实是被查询的对象。<code>__eq__</code>在最后一个例子中没有调用,因为dict中没有一个对象具有与<code>Foo(4)</code>相同的哈希值,因此Python不需要继续使用<code>__eq__</code>。在</p>
^{pr2}$
<p>在此版本中,所有对象都具有相同的哈希值。在这种情况下,<code>__eq__</code>总是被调用,有时是多次调用,因为哈希不区分值,所以Python需要根据dict中的所有值显式地检查相等性,直到找到一个相等的值(或者发现它们都不等于它要查找的值)。有时它在第一次尝试时找到它(上面的<code>Foo(1) in dict</code>),有时它必须检查所有的值。在</p>