为什么包含不可变类型的元组不可用?

时间:2017-10-17 04:53:58

标签: python

例如,元组(1,[0,1,2])。我从设计的角度理解为什么;如果元组仍然可以清除,那么通过将它包装在一个元组中来使任何不可变类型可以清除它将是微不足道的,这会打破正常的可执行行为,因为您可以在不更改元组的哈希值的情况下更改对象的值。但是如果元组不可以清除,那么我就不会理解是什么让一个对象可以清除 - 我认为它只需要实现__hash__(self),这个元组就是这样。

基于我已经看过的其他答案,从测试示例来看,似乎这样的对象不可清除。似乎合情理的行为是tuple.__hash__()为其组件对象调用__hash__,但我不了解如何从实现的角度来看,例如我还不知道当字典仍然是类型元组时字典会将其识别为不可变类型,而元组仍定义__hash__

2 个答案:

答案 0 :(得分:3)

tuple通过计算和组合它包含的值的哈希值来实现自己的哈希值。当散列其中一个值失败时,它会使得生成的异常无阻碍地传播。

不可取仅意味着在您上面调用hash()会触发TypeError;一种方法是不定义__hash__方法,但如果在__hash__方法中你提出TypeError(或任何其他错误),它同样有效通过其他方式。

基本上,tuple是一种可散列的类型(isinstance((), collections.abc.Hashable)是真的,因为它是isinstance(([],), collections.abc.Hashable)存在的类型级别检查,但如果是__hash__存储不可变类型,任何计算哈希值的尝试都会在使用时引发异常,因此行为就像在该场景中的不可用类型一样。

答案 1 :(得分:2)

我假设tuple.__hash__()为元组中的每个项目调用hash(item),然后将结果与XOR结合在一起。如果其中一个项目无法播放,那么会引发一个TypeError冒充到原来的来电者。