首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在python中实现一个好的__hash__函数

如何在python中实现一个好的__hash__函数
EN

Stack Overflow用户
提问于 2010-10-24 01:54:24
回答 2查看 87K关注 0票数 114

当实现具有多个属性的类时(如下面的玩具示例),处理散列的最佳方法是什么?

我猜__eq____hash__应该是一致的,但是如何实现一个能够处理所有属性的合适的哈希函数呢?

代码语言:javascript
复制
class AClass:
  def __init__(self):
      self.a = None
      self.b = None

  def __eq__(self, other):
      return other and self.a == other.a and self.b == other.b

  def __ne__(self, other):
    return not self.__eq__(other)

  def __hash__(self):
      return hash((self.a, self.b))

我在this question上读到元组是可哈希的,所以我想知道上面的例子是不是很合理。是吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-10-24 02:19:42

对于相等的对象,__hash__应返回相同的值。它也不应该在对象的生命周期中改变;通常你只为不可变的对象实现它。

一个微不足道的实现就是return 0。这总是正确的,但性能很差。

您的解决方案,返回一个属性元组的散列,是很好的。但请注意,您不需要在元组中列出在__eq__中比较的所有属性。如果某些属性对于不相等的对象通常具有相同的值,则将其省略。不要使散列计算比需要的更昂贵。

编辑:一般情况下,我建议不要使用xor来混合哈希。当两个不同的属性具有相同的值时,它们将具有相同的散列,并且使用xor,这些散列将相互抵消。元组使用更复杂的计算来混合哈希,请参见tupleobject.c中的tuplehash

票数 88
EN

Stack Overflow用户

发布于 2012-09-20 19:31:08

写是很危险的

代码语言:javascript
复制
def __eq__(self, other):
  return other and self.a == other.a and self.b == other.b

因为如果您的rhs (即other)对象的计算结果为布尔值False,那么它将永远不会等于任何东西!

此外,您可能希望仔细检查other是否属于AClass的类或子类。如果不是这样,您将得到异常AttributeError或误报(如果另一个类恰好具有同名属性和匹配值)。因此,我建议将__eq__重写为:

代码语言:javascript
复制
def __eq__(self, other):
  return isinstance(other, self.__class__) and self.a == other.a and self.b == other.b

如果您想要一个异常灵活的比较,只要属性按名称匹配,就可以在不相关的类之间进行比较,那么您仍然希望至少避免AttributeError,并检查other是否没有任何额外的属性。如何做到这一点取决于具体情况(因为没有标准的方法来查找对象的所有属性)。

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4005318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档