collections.abc 的实施不一致
Inconsistent implementation of collections.abc
我正在尝试理解 collections.abc
源代码。
让我们来看看 Hashable
class' __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
class.
中也有此逻辑
和AsyncIterable
class' __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___
属性,这个逻辑在这个包中的任何其他 classes 中都存在。
这种逻辑差异有什么原因吗?
__hash__
protocol 通过设置 __hash__ = None
.
明确允许将 class 标记为不可哈希
If a class [...] wishes to suppress hash support, it should include __hash__ = None
in the class definition.
原因是 a == b
总是需要 hash(a) == hash(b)
。否则,dict
、set
和类似的数据结构会中断。如果 child class 明确或以其他方式更改 __eq__
,这可能不再适用。因此,__hash__
可以标记为不适用。
我正在尝试理解 collections.abc
源代码。
让我们来看看 Hashable
class' __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
class.
和AsyncIterable
class' __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___
属性,这个逻辑在这个包中的任何其他 classes 中都存在。
这种逻辑差异有什么原因吗?
__hash__
protocol 通过设置 __hash__ = None
.
If a class [...] wishes to suppress hash support, it should include
__hash__ = None
in the class definition.
原因是 a == b
总是需要 hash(a) == hash(b)
。否则,dict
、set
和类似的数据结构会中断。如果 child class 明确或以其他方式更改 __eq__
,这可能不再适用。因此,__hash__
可以标记为不适用。