python文档中的解释:
hashable
An object is hashable if it has a hash value which never changes during its lifetime (it needs a _hash_() method), and can be compared to other objects (it needs an __eq__() method). Hashable objects which compare equal must have the same hash value.
Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.
All of Python's immutable built-in objects are hashable; mutable containers (such as lists or dictionaries) are not. Objects which are instances of user-defined classes are hashable by default. They all compare unequal (except with themselves),and their hash value is derived from their id().
一个对象是可散列的,那么在它的生命周期中它的hash 值是不变的。可散列的对象需要2个方法:__hash__()方法和__eq__()方法。两个可散列的对象相等,那么它们的散列值相等。
可散列的对象可以作为字典的key,作为set的成员。但是字典,set本身是不可散列的。
Python所有内置的不可变的对象都是hashable,可变的容器(比如lists或dictionaries)不是hashable。用户定义的类的对象默认是hashable的,它们的hash值来自它们的id()。
id(object)
Return the "identity" of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.
Python hash()函数
描述
hash() 用于获取取一个对象(字符串或者数值等)的哈希值。
语法
hash语法:
hash(object)
参数说明:
object -- 对象;
返回值
返回对象的哈希值。
实例
以下实例展示了 hash 的使用方法:
a = 'test'
hash(a)
9200364911530798280
hash(1)
1
hash(set([1,2,3]))
Traceback (most recent call last):
Python Shell, prompt 54, line 1
builtins.TypeError: unhashable type: 'set'
hash(str(set([1,2,3])))
8296610150693321573
可见, hash() 函数可以应用于数字、字符串和对象,不能直接应用于 list、set、dictionary。
在 hash() 对对象使用时,所得的结果不仅和对象的内容有关,还和对象的 id(),也就是内存地址有关。
class Test:
def __init__(self, i):
self.i = i
for i in range(10):
t = Test(1)
print(hash(t), id(t))
输出结果:
120186414364 1922982629824
120186414394 1922982630304
120186414364 1922982629824
120186414394 1922982630304
120186414364 1922982629824
120186414394 1922982630304
120186414364 1922982629824
120186414394 1922982630304
120186414364 1922982629824
120186414394 1922982630304
由上可得, 在循环10次实例化Test类时, 该实例object默认是hashable的, 这一点在上文已经有过说明. 进而, 每一次循环中实例的hash值和id值是会变的, 当然, 由于内存分配的问题, 本次循环中一共用了2个hash值和id值, 之后它们与之前的循环相同并不意味着可以一一对应, 这是因为:
Two objects with non-overlapping lifetimes may have the same id() value.
也就是说, 后面循环出来的具有相同hash和id值的object是一个新的lifetime的实例.
最后, 再次强调一下, 列表,字典,集合是无法散列的,因为它们在改变值的同时却没有改变id,无法由地址定位值的唯一性,因而无法散列。