gpt4 book ai didi

python - 解决Python中abc.Sequence、abc.Hashable、list的继承矛盾

转载 作者:太空狗 更新时间:2023-10-30 01:17:59 24 4
gpt4 key购买 nike

我使用的是 3.6.3 版本

我正在研究 Python collections.abc 类之间的继承关系。我发现 listSequenceHashable

之间存在一些矛盾的继承

如你所知,
1、Sequence继承Hashable
2、list继承Sequence

from collections import Sequence, Hashable


issubclass(Sequence, Hashable) # 1.
issubclass(list, Sequence) # 2.

True
True

据此,您可能会认为 list 在概念上也继承了 Hashable

但是 list 是可变的,它不继承 Hashable(意思是“你不能”hash(some_list)')

issubclass(list, Hashable)


False

我觉得这种继承是矛盾的。我完全理解 list 是可变的,因为我已经使用了数百次 list 但继承关系图不支持这个概念。我错了什么或遗漏了什么?

我在等你的建议。谢谢。

最佳答案

所以它实际上是一个有趣的设计特性,但 Python 子类实际上并不需要传递。谷歌定义的传递:

"if a trait is applicable between successive members of a sequence, it must also apply between any two members taken in order. For instance, if A is larger than B, and B is larger than C, then A is larger than C."

对于继承是可传递的语言,比如Java,如果B继承AC继承B ,那么 C 必须继承 AC 的传递父类(super class)集是 ABObject,以及直接父类(super class)是 B

在 Python 中,我们背离了这个概念。正如您所指出的,SequenceHashablelistSequence,但是 list 不是 Hashable。事实上,list 不直接继承任何东西(除了每个 python 类继承的 object)

# from the PyCharm generated stubs
class list(object):
...

在 Python 中,您可以使用元类实用程序中的 __subclasscheck____subclasshook__ 来使内置方法 issubclass 执行有趣的操作。元类是一种高级语言功能,用于修改关于类如何操作的基本规则(修改issubclass 的工作方式就是一个很好的例子)。在抽象基类元类 ABCMeta 中,__subclasscheck__ 方法将在定义类时调用 __subclasshook__ 方法。你可以阅读一个great answer about the uses here .

某些 ABCMeta 类,如 Hashable 实现 __subclasshook__ 不检查继承树,而是检查方法是否存在。这很有用,这样就不必在您创建的每个类定义中都包含通用契约。

对于这种情况,为了成为Hashable,您需要定义__hash__。但是,Python 声明不对 List 进行哈希处理,因为它是可变的,因此从此类中专门省略了它。

class Hashable(metaclass=ABCMeta):

__slots__ = ()

@abstractmethod
def __hash__(self):
return 0

@classmethod
def __subclasshook__(cls, C):
if cls is Hashable:
return _check_methods(C, "__hash__")
return NotImplemented

class list(object):
...
__hash__ = None

关于python - 解决Python中abc.Sequence、abc.Hashable、list的继承矛盾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55997924/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com