【问题标题】:Inconsistent implementation of collections.abccollections.abc 的实现不一致
【发布时间】:2016-07-09 14:10:10
【问题描述】:

我正在尝试理解collections.abc 源代码。

我们来看看Hashableclass'__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___属性,并且这个逻辑在这个包中的任何其他类中都有。

这种逻辑差异有什么原因吗?

【问题讨论】:

    标签: python python-3.x abc


    【解决方案1】:

    __hash__ protocol 明确允许通过设置 __hash__ = None 将类标记为不可散列。

    如果一个类 [...] 希望抑制散列支持,它应该在类定义中包含 __hash__ = None

    原因是a == b 总是需要hash(a) == hash(b)。否则,dictset 和类似的数据结构会中断。如果子类显式或以其他方式更改__eq__,这可能不再适用。因此,__hash__ 可以被标记为不适用。

    【讨论】:

    • 但这并不能解释为什么 Awaitable 也会这样做。
    • @Bakuriu 我推测它来自复制粘贴,看看Awaitable 是如何在Hashable 之后定义的。 docs 提到 Awaitable 并不总是正常工作,因此 ABC 可能没有最终确定。严格来说,无论如何都没有禁止其他 ABC 对Hashable 进行检查。
    猜你喜欢
    • 1970-01-01
    • 2015-01-08
    • 2019-08-09
    • 2016-02-09
    • 1970-01-01
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多