Python中的哈希

基础

1、什么是可哈希(hashable)?哪些类型是可哈希的?

参考 python可变与可哈希

2、Python的哈希值和哈希集

Python内置了hash()方法,能够返回可哈希对象的哈希值(一个整数)。对于这个整数我们需要了解,这个整数在一个Python进程中是唯一而且保持不变的,但它们的值在重复运行的 Python 间是不可预测的。那么我们可以根据这个哈希值搭建很多以此为依据的数据类型-称为哈希集。Pyhotn中的哈希集有set、frozenset、dict。
对于哈希集中的对象一定都是可哈希的,比如字典的KEY不能够是列表,因为列表不可哈希,同时集合的元素不能够包含列表,字典,以及集合。

默认自定义类

用户自定义的类默认带有__eq__()和__hash__()方法。默认使它们与任何(自己除外)对象必定不同,意思是x.hash()会返回一个恰当的值确保 x==y 同时 x is y 同时 hash(x) == hash(y)

重载__hash__(self)

Python内置的hash()方法调用的就是__hash__()魔法方法,根据官方建议:it is advised to mix together the hash values of the components of the object that also play a part in comparison of objects by packing them into a tuple and hashing the tuple.最大化使用对象中有哈希值的成员构成的元组,并返回元组的哈希值。这里有一个官方的实例:

def __hash__(self):
	return hash((self.name, self.nick, self.color))

只重载__eq__()

如果一个用户自定义类只重载了__eq__()而没有重载__hash__()则会将其__hash__()隐式的设置为None。当一个类的__hash__()为None时,该类的实例将在一个程序尝试获取其哈希值时正确的引发TypeError,并会在检测isinstance(obj, collections.abc.Hashable)时被正确的识别为不可哈希对象。

# 1、可哈希自定义类
class A(object):
	pass

class B(object):
	
	def __init__(self, value1, value2):
		slef.value1 = value1
		self.value2 = value2
	
	def __eq__(self, other):
		if isinstance(other, self.__class__):
			if self.value1 == other.value1 and self.value2 == other.value2:
				return True
		return False

	def __hash__(self):
		return hash((self.value1, self.value2))
# 2、不可哈希自定义类(隐式)
class C(object):
	
	def __init__(slef, value1, value2):
		self.value1 = value1
		slef.value2 = value2

	def __eq__(self, other):
		if isinstance(other, self.__class__):
			if self.value1 == other.value1 and self.value2 == other.value2:
				return True
		return False

>>> c = C(1, 2)
>>> isinstance(c, collections.abc.Hashable)
>>> False # 因为只重载__eq__方法,__hash__被隐式置为None,尝试访问其哈希值时会抛出异常
# 3、显式定义不可哈希类
class D(object):
	def __init__(slef, value1, value2):
		self.value1 = value1
		slef.value2 = value2

	def __eq__(self, other):
		if isinstance(other, self.__class__):
			if self.value1 == other.value1 and self.value2 == other.value2:
				return True
		return False

	def __hash__(self):
		return hash((self.value1, self.value2))

>>> d = D(1, 3)
>>> isinstance(d, collections.abc.Hashable))
>>> True

你可能感兴趣的:(python高级)