19

python 文档提到,如果您覆盖并且__eq__对象是不可变的,您还应该覆盖__hash__以使该类正确可散列。

在实践中,当我这样做时,我经常会得到类似的代码

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

    def __eq__(self, other):
        if type(other) is type(self):
            return (self.a == other.a) and (self.b == other.b)
        else:
            return False

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

这有点重复,并且在更新另一个时忘记更新一个明显的风险。

有没有推荐的方法一起实现这些方法?

4

3 回答 3

24

回答我自己的问题。似乎执行此操作的一种方法是定义一个辅助__members函数并将其用于定义__hash__and __eq__。这样,没有重复:

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

    def __members(self):
        return (self.a, self.b)

    def __eq__(self, other):
        if type(other) is type(self):
            return self.__members() == other.__members()
        else:
            return False

    def __hash__(self):
        return hash(self.__members())
于 2017-07-18T15:03:59.117 回答
-1

这相当于这个单线eq吗?

   def __eq__(self, other):
       return type(other) is type(self) and (self.a == other.a) and (self.b == other.b)
于 2021-01-19T23:00:07.157 回答
-3

我认为您可以使用用户定义的哈希函数更好。

class MyClass(object):

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

def __eq__(self, other):
    if type(other) is type(self):
        return (self.a, self.b) == (other.a, other.b)
    else:
        return NotImplemented

def __hash__(self):
    return hash((self.a, self.b))
于 2021-09-30T02:29:48.163 回答