1异常

小伙伴们,平时遇到过下面这个 TypeError 异常吗?

这个 TypeError 翻译过来---类型错误:不可哈希的类型:'list'

2原因

既然有不可哈希(unhashable),就会有可哈希(hashable)类型。那么,什么类型为可哈希? 引用 Python3 官方解释:

一个对象的哈希值如果在其生命周期内绝不改变,就被称为 可哈希 (它需要具有hash() 方法),并可以同其他对象进行比较(它需要具有eq() 方法)。可哈希对象必须具有相同的哈希值比较结果才会相同。

一个对象的哈希值在生命周期内不改变,就被成为 可哈希。可哈希性使得对象能够作为字典键或集合成员使用,因为这些数据结构要在内部使用哈希值。

可变容器(例如列表或字典)都不可哈希。所以,回过头来看文章开头的 TypeError ,就容易解释了,只有可哈希对象才能作为字典的键。

同样,文章开头的列表 a ,也不能作为集合成员使用,否则,也会抛出同样的异常,如下所示:

3评价哈希值

如何评判一个对象的哈希值是否改变呢?一般地,

1、所有 Python 中的不可变内置对象都是可哈希的;

2、可变容器(例如列表或字典)都不可哈希。

3、用户定义类的实例对象默认是可哈希的。

4计算哈希值

Python 中的 hash 函数用来计算对象的哈希值。相等的两个对象一定拥有相等的哈希值,反过来却不成立。

相等的对象 mys 和 comb 必然具有相等的哈希值,如下所示:

而不可哈希的对象,是没有哈希值的,比如字典 di. 原因是set()和dict()使用对象的hash 值作为内部索引,以便能快速索引到指定对象。因此,作为字典键的类型,必须为可哈希的,并且可哈希的对象必须确保每次返回相同的 hash 值,这样才能确保字典的正常工作。

总结

1、大家首先要知道:抛出对象不可哈希的类型这个异常时,是怎么回事

2、字典和集合的键类型必须为可哈希的

3、可哈希对象的属性值一定是不能被修改的,如果自己定义的可哈希对象,随意修改属性值,会发生不可预见的行为。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐