实现具有多个属性的类时(如下面的玩具示例),处理散列的最佳方法是什么?
我猜测,__eq__而__hash__应该是一致的,但如何实现适当的哈希函数,能够处理所有属性?
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))
我读到这个问题,元组是可以清洗的,所以我想知道上面的例子是否合情合理.是吗?
adw*_*adw 71
__hash__应该为相等的对象返回相同的值.它也不应该在对象的生命周期内改变; 通常,您只为不可变对象实现它.
一个简单的实现将是公正的return 0.这总是正确的,但表现不好.
你的解决方案,返回一个属性元组的哈希是好的.但请注意,您不需要列出__eq__在元组中比较的所有属性.如果某些属性对于不等对象通常具有相同的值,则只需将其保留.不要使哈希计算比它需要的更昂贵.
编辑:我建议不要使用xor来混合哈希.当两个不同的属性具有相同的值时,它们将具有相同的散列,并且对于xor,这些将取消彼此.元组使用更复杂的计算混合散列,见tuplehash在tupleobject.c.
S.L*_*ott 14
唯一需要的属性是比较相等的对象具有相同的哈希值; 建议以某种方式将对象的组件的哈希值混合在一起(例如,使用异或),这些哈希值也在对象的比较中起作用.
def __hash__(self):
    return hash(self.a) ^ hash(self.b)
max*_*max 12
写作很危险
def __eq__(self, other):
  return other and self.a == other.a and self.b == other.b
因为如果你的rhs(ie,other)对象的计算结果为布尔值False,那么它永远不会与任何东西相等!
此外,您可能需要仔细检查是否other属于类或子类AClass.如果没有,您将获得异常AttributeError或误报(如果其他类恰好具有匹配值的相同命名属性).所以我建议重写__eq__为:
def __eq__(self, other):
  return isinstance(other, self.__class__) and self.a == other.a and self.b == other.b
如果你想要一个非常灵活的比较,只要属性按名称匹配,就可以比较不相关的类,你仍然希望至少避免AttributeError并检查other它没有任何其他属性.你如何做到这取决于情况(因为没有标准的方法来查找对象的所有属性).
| 归档时间: | 
 | 
| 查看次数: | 56539 次 | 
| 最近记录: |