代码之家  ›  专栏  ›  技术社区  ›  DeepSpace

继承-在子类中\uuuu散列\uuuuu设置为无

  •  3
  • DeepSpace  · 技术社区  · 7 年前

    考虑:

    class Comparable:
        def _key(self):
            raise NotImplementedError
    
        def __hash__(self):
            return hash(self._key())
    
        def __eq__(self, other):
            ...
    
        def __lt__(self, other):
            ...
    
    
    class A(Comparable): pass
    
    class B(A):
        def __str__(self):
            return "d"
    
        def __eq__(self, other):
            return isinstance(self, type(other))
    
        def _key(self):
            return str(self),
    
    b = B()
    

    很明显,人们会期望 b.__hash__ Comparable 哪一个 B 是的一个子类。

    瞧,它被定义了,但计算结果是 None . 有什么好处?

    >> b
    <__main__.B object at 0x00000183C9734978>
    >> '__hash__' in dir(b)
    True
    >> b.__hash__
    
    >> b.__hash__ is None
    True
    >> B.__mro__
    (<class '__main__.B'>, <class '__main__.A'>, <class '__main__.Comparable'>, <class 'object'>)
    >> isinstance(b, Comparable)
    True
    

    __init__ super().__init__() 可比较的 和 A .

    1 回复  |  直到 7 年前
        1
  •  15
  •   kabanus    7 年前

    发现它在 the docs :

    __eq__() 并且没有定义 __hash__() 会有它的 隐式设置为“无”。

    和

    如果一个类重写了 __等式 需要保留执行 __散列 从父类中,必须通过设置 __hash__ = <ParentClass>.__hash__

    从票上 1549 :

    这是故意做的——如果您定义一个比较而没有 定义散列时,默认散列将与比较不匹配,并且 当用作字典键时,您的对象将表现不正常。

    (吉多·范罗瑟姆)