当实现具有多个属性的类(如下面的玩具示例中所示)时,处理散列的最佳方法是什么?
我想__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))
我在this question上读到元组是散列的,所以我想知道上面的例子是否合理。它是?
__hash__
应该为相等的对象返回相同的值。它也不应该随着对象的生命周期而改变;通常,您只为不可变对象实现它。一个简单的实现就是
return 0
。这总是正确的,但表现不好。您的解决方案,返回属性元组的散列,是很好的。但是请注意,您不需要列出在元组的
__eq__
中比较的所有属性。如果某个属性对于不相等的对象通常具有相同的值,请忽略它。不要让散列计算比需要的更昂贵。编辑:我建议一般不要使用xor来混合散列。当两个不同的属性具有相同的值时,它们将具有相同的散列,而使用xor时,这些属性将彼此取消。元组使用更复杂的计算来混合散列,请参见^{} 中的
tuplehash
。写东西很危险
因为如果rhs(即
other
)对象的计算结果为boolean False,那么它永远不会与任何对象进行比较!此外,您可能需要再次检查
other
是否属于AClass
的类或子类。如果没有,您将获得异常AttributeError
或假阳性(如果另一个类碰巧具有具有匹配值的相同命名属性)。因此,我建议将__eq__
重写为:如果您希望进行异常灵活的比较(只要属性按名称匹配,就可以跨不相关的类进行比较),那么您至少应该避免
AttributeError
,并检查other
没有任何其他属性。这取决于具体情况(因为没有标准的方法可以找到对象的所有属性)。^{} 的文档
相关问题 更多 >
编程相关推荐