继承-__hash__在子类中设置为None [英] Inheritance - __hash__ sets to None in a subclass
问题描述
我设法在Python 3.4和3.7上重现了这一点.
I managed to reproduce this on both Python 3.4 and 3.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
是其子类.
Clearly one would expect b.__hash__
to be defined here, since it is defined under Comparable
which B
is a subclass of.
Lo并已定义,但计算结果为None
.有什么作用?
Lo and behold, it is defined, but evaluates to None
. What gives?
>> 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
如果在Comparable
和A
中将__init__
实现为super().__init__()
,则会再现相同的行为.
The same behavior is reproduced if implementing __init__
as super().__init__()
in Comparable
and A
.
推荐答案
在
重写 A class that overrides 和 如果重写 If a class that overrides 从故障单 1549 : 这是有意完成的-如果您定义的比较没有
定义哈希,默认哈希将不匹配您的比较,并且
当用作字典键时,您的对象将无法正常工作. This was done intentionally -- if you define a comparison without
defining a hash, the default hash will not match your comparison, and
your objects will misbehave when used as dictionary keys. (Guido van Rossum) (Guido van Rossum) 这篇关于继承-__hash__在子类中设置为None的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!__eq__()
并且未定义__hash__()
的类将其__hash__()
隐式设置为None.
__eq__()
and does not define __hash__()
will have its __hash__()
implicitly set to None.
__eq__()
的类需要保留父类中__hash__()
的实现,则必须通过设置__hash__ = <ParentClass>.__hash__
__eq__()
needs to retain the implementation of __hash__()
from a parent class, the interpreter must be told this explicitly by setting __hash__ = <ParentClass>.__hash__