我试图了解collections.abc
源代码。
让我们来看看Hashable
课程' __subclasshook__
实施:
@classmethod
def __subclasshook__(cls, C):
if cls is Hashable:
for B in C.__mro__:
if "__hash__" in B.__dict__:
if B.__dict__["__hash__"]:
return True
break
return NotImplemented
这里我们首先检查是否存在属性hash
,然后检查它是否具有非假值。这个逻辑也出现在Awaitable
类中。
AsyncIterable
课程' __subclasshook__
:
@classmethod
def __subclasshook__(cls, C):
if cls is AsyncIterable:
if any("__aiter__" in B.__dict__ for B in C.__mro__):
return True
return NotImplemented
这里我们只检查是否有__aiter___
属性,并且此逻辑在此包中的任何其他类中显示。
这种逻辑差异是否有任何原因?
答案 0 :(得分:3)
__hash__
protocol明确允许通过设置__hash__ = None
将类标记为不可用。
如果一个类[...]希望抑制哈希支持,它应该在类定义中包含
__hash__ = None
。
原因是a == b
总是需要hash(a) == hash(b)
。否则,dict
,set
和类似的数据结构会中断。如果子类明确地或以其他方式更改__eq__
,则可能不再适用。因此,__hash__
可以被标记为不适用。