持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
0 环境
- 编辑器:pycharm或者vscode
- 系统版本:windows10
- python版本:3.9.6
1 认识__hash__
一说起来hash来,一般都用到过hash加盐,有时候会看到在类写__hash__方法。
这里的hash从哪里来的呢,类继承object,object里有个hash的方法。如下图。也就说上面的方式,其实是重写hash方法。使用hash内置函数对需要的对象求取hash值,会调用对象的__hash__方法。
还有一点注意的就是必须是int类型,哪怕是返回None也是不可以的,如下图的错误提示。
如果你想对象不可hash,可在类里加,hash = None。效果如下。
想要对象可被hash,需要存在__hash__,并且返回值是个int,不想有__hash__直接置为None。
假如我们没有重写hash,下面定义的两个实例的hash值是不一样的。如下所示:
class Demo1:
def __init__(self, a):
self.a = a
print(hash(Demo1(1)))
print(hash(Demo1(2)))
我打印两次hash(Demo1(1)),希望它的hash是一样的。可以使用如下方式。
class Demo1:
def __init__(self, a):
self.a = a
def __hash__(self):
return hash(f'{self.a}')
print(hash(Demo1(1)))
print(hash(Demo1(1)))
虽然hash最后的结果是一致的,但是它俩比较一下,最终的结果是False。怎么样才能真正相等呢,还缺个__eq__需要实现一下。
class Demo1:
def __init__(self, a):
self.a = a
def __hash__(self):
return hash(f'{self.a}')
print(hash(Demo1(1)))
print(hash(Demo1(1)))
d = Demo1(1)
d1 = Demo1(1)
print(d == d1)
2 总结
hash来自于object,而对于所有的类来说,他们的爸爸或者祖宗来说object,也就说它们天然的带有这个方法,假如想不一样,可以重写hash,注意了,返回值是有讲究的,非int不可,如果你不想对象可hash,可以将__hash赋值为None即可,要想hash一样,重写__hash__。