Python __hash__用于等值对象 [英] Python __hash__ for equal value objects

查看:88
本文介绍了Python __hash__用于等值对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一些Person实体,并且想知道其中是否有人在列表中:

  person in person? 

我不在乎'对象的ID'是什么,只是它们的属性是相同的。所以我把它放在我的基类中:

 #value comparison only only 
def __eq __(self,other):
return(isinstance(other,self .__ class__)and self .__ dict__ == other .__ dict__)

def __ne __(self,other):
return not self .__ eq __(other )

但是为了能够测试集合中的相等性,我还需要定义散列

 #sets使用__hash__进行相等比较
def __hash __(self):
return(
self.PersonID,
self.FirstName,
self.LastName,
self.etc_etc ...
).__ hash __()

问题是我不想列出每个属性,而且我不想修改<每当属性发生变化时,我们都会使用strong> hash 函数。



那么可以这样做吗?

 #sets使用__hash__进行相等比较
def __hash __(self):
values = t uple(self .__ dict __。values())
返回哈希(值)

理智,而不是 toooo 大部分的表现损失?在一个网络应用的情况。



非常感谢。

字典的无序性意味着如果字典元组(self .__ dict __。values()) (这可能发生,例如,如果一个人的属性以不同的顺序分配的话)。



因为你的 values 是可哈希的,你可以试试这个:

  return hash(frozenset(self .__ dict__ .iteitems()))

或者,请注意 __ hash __ 不需要考虑所有因素,因为当散列值比较相等时,仍然会使用 __ eq __ 来验证相等性。因此,你可能会逃避

  return hash(self.PersonID)

假设 PersonID 在不同实例中是相对唯一的。


Say I have some Person entities and I want to know if one is in a list:

person in people?

I don't care what the 'object's ID' is, just that their properties are the same. So I put this in my base class:

# value comparison only
def __eq__(self, other):
    return (isinstance(other, self.__class__) and self.__dict__ == other.__dict__)

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

But to be able to test for equality in sets, I also need to define hash So...

# sets use __hash__ for equality comparison
def __hash__(self):
    return (
        self.PersonID,
        self.FirstName,
        self.LastName,
        self.etc_etc...
    ).__hash__()

The problem is I don't want to list every property, and I don't want to modify the hash function every time the properties change.

So is it okay to do this?

# sets use __hash__ for equality comparison
def __hash__(self):
    values = tuple(self.__dict__.values())
    return hash(values)

Is this sane, and not toooo much of a performance penalty? In a web-app situation.

Thanks muchly.

解决方案

The unordered nature of dictionaries means that tuple(self.__dict__.values()) is prone to producing different results if the dicts happen to be ordered differently (which could happen, for example, if one had its attributes assigned in a different order).

Because your values are hashable, you could try this instead:

return hash(frozenset(self.__dict__.iteritems()))

Alternatively, note that __hash__ does not need to take everything into account because __eq__ will still be used to verify equality when the hash values compare equal. Therefore, you can probably get away with

return hash(self.PersonID)

assuming PersonID is relatively unique across instances.

这篇关于Python __hash__用于等值对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆