如果我们制作这样的病态土豆:
>>> class Potato:
... def __eq__(self, other):
... return False
... def __hash__(self):
... return random.randint(1, 10000)
...
>>> p = Potato()
>>> p == p
False
Run Code Online (Sandbox Code Playgroud)
我们可以通过这种方式打破集合和切换(注意:即使__eq__返回True它也是一样的,它正在破坏它们的哈希):
>>> p in {p}
False
>>> p in {p: 0}
False
Run Code Online (Sandbox Code Playgroud)
此外len({p: 0, p: 0}) == 2,并{p: 0}[p]引发KeyError,基本上所有与映射相关的东西都会出现,如预期的那样.
但我没想到的是我们不能打破名单
>>> p in [p]
True
Run Code Online (Sandbox Code Playgroud)
这是为什么?它似乎是list.__contains__迭代,但它首先在检查相等性之前检查身份.由于不是身份意味着相等的情况(例如参见NaN对象),列表在身份比较中短路的原因是什么?