python - 类自定义 __eq__ 作为哈希值的比较

标签 python class hash equality

考虑自定义类:

class MyObject:
    def __init__(self, a, b):
        self.a = a
        self.b = b

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

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.__hash__() == other.__hash__()

让平等依赖于哈希是一个坏主意吗?与以零碎的方式检查每对属性以获取大量属性相比,这似乎是一种更加优雅和可读的机制

self.a == other.a and self.b == other.b and ... self.n == other.n

或者使用 getattr 和列表进行更动态的检查(是否有更好的方法来比较大量属性对?)

内置哈希函数返回的哈希大小是否不够大,在相对较大的数据集中无法可靠?

最佳答案

是的,这是一个坏主意。哈希值不是唯一的,具有相等哈希值的对象不能保证实际上也相等:

>>> (-1, 0) == (-2, 0)
False
>>> hash((-1, 0)) == hash((-2, 0))
True

哈希值并不意味着是唯一的;它们是在有限尺寸 hash table 中选择插槽的一种方法。快速,以促进 O(1) 字典查找,并且允许且预期发生冲突

是的,Python 要求相等的对象应该具有相等的哈希值,但这并不意味着关系可以颠倒。

我只是比较元组:

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

如果您正在编写大量数据类、都需要相等测试和哈希等的简单类,请使用 dataclasses module (Python 3.7 或更高版本,或使用 backport ):

from dataclasses import dataclass

@dataclass(frozen=True)
class MyObject:
    a: int
    b: int

上面的类现在带有 __hash____equals__ 方法:

>>> MyObject(-1, 0) == MyObject(-2, 0)
False
>>> hash(MyObject(-1, 0)) == hash(MyObject(-2, 0))
True
>>> MyObject(42, 12345) == MyObject(42, 12345)
True

关于python - 类自定义 __eq__ 作为哈希值的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54944398/

相关文章:

python - 在 Matplotlib 中循环创建子图?

php - 将 md5 密码哈希值转换为 PHP 5.5 password_hash()

javascript - "switch"中的函数不起作用

python - 如何使用 QueryString 启动网站?

python - 每个唯一值采样一条记录( Pandas , python )

c++ - 为什么我更改了子项中的父虚函数参数隐藏了父函数 C++?

java - 获取包中声明的所有 Java 类的名称

c# - 使用 ASP.NET MVC 3 散列密码

python - 避免在多对多 rel SQLAlchemy 中检索要删除的对象

php - 单独的类方法声明和定义?