解决Python中abc.Sequence、abc.Hashable和list之间的继承矛盾
我使用的是3.6.3版 我正在研究Python解决Python中abc.Sequence、abc.Hashable和list之间的继承矛盾,python,abc,Python,Abc,我使用的是3.6.3版 我正在研究Pythoncollections.abc类之间的继承关系。我发现列表,序列和哈希表 如您所知, 1. 序列继承哈希类和 2. 列表继承序列 从集合导入序列,可散列 issubclass(序列,可散列)#1。 issubclass(列表、序列)#2。 真的 真的 从这一点上,您可能会认为列表在概念上也继承了哈希表 但是列表是可变的,它不会继承哈希表(意思是“你不能”哈希表(一些列表)” issubclass(列表,可哈希) 假的 我认为这种继承是矛盾的。我完
collections.abc
类之间的继承关系。我发现列表
,序列
和哈希表
如您所知,1.
序列
继承哈希类
和2.
列表
继承序列
从集合导入序列,可散列
issubclass(序列,可散列)#1。
issubclass(列表、序列)#2。
真的
真的
从这一点上,您可能会认为列表
在概念上也继承了哈希表
但是列表
是可变的,它不会继承哈希表
(意思是“你不能”哈希表(一些列表)”
issubclass(列表,可哈希)
假的
我认为这种继承是矛盾的。我完全理解list
是可变的,因为我已经使用list
数百次了,但是继承关系图不支持这个概念。我错了或错过了什么
我在等你的告别。谢谢。所以它实际上是一个有趣的设计特性,但是Python子类实际上不需要是可传递的。谷歌定义的可传递性: 如果一个特征适用于一个序列的连续成员,它必须也适用于按顺序选取的任何两个成员。例如,如果a大于B,B大于C,则a大于C 对于继承是可传递的语言,如Java,如果
B
继承A
和C
继承B
,则C
必须继承A
。C
的可传递超类集将是A
、B
和对象
,直接超类是B
在Python中,我们背离了这个概念。正如您所指出的,序列
是可散列的,列表
是可散列的,但列表
不是可散列的。事实上,list并没有直接继承任何东西(除了每个python类继承的object
)
在Python中,您可以使用元类实用程序中的\uuuuuu subasscheck\uuuuu
或\uuuuuuuu subasshook\uuuuuu
使内置方法issubclass
执行有趣的操作。元类是一种高级语言功能,用于修改有关类如何操作的基本规则(修改issubclass
的工作方式就是一个很好的例子)。在抽象基类元类ABCMeta
中,\uuuuuu subasscheck\uuuuu
方法将调用类上的\uuuuuuu subasshook\uuuuu
方法(如果已定义)。你可以读一本书
某些ABCMeta
类,如Hashable
实现\uuu子类hook\uuuu
以不检查继承树,而是检查方法的存在。这很有帮助,这样就不必在所做的每个类定义中都包含公共契约
在这种情况下,为了能够散列
,您需要定义\uuuuuu散列
。然而,Python声明不在列表上散列,因为它是可变的,因此在这个类中特别省略了它
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
你看过这个博客吗?这看起来很好,这里有一个引语,“…Iterable是Hashable的一个“子类”——说真的,因为Iterable有它从object继承的
\uuuuuhash\ucode>方法,Sequence
有一个\uhash\uuhash
方法,但是根据,Sequence
没有从Hashable
继承。(不是回答,只是观察。)@SuperShoot谢谢你的推荐。我非常喜欢这种方法:用Python获取所有类并测试所有三元组依赖性检查。我想我以后应该深入研究元类。)我也把它加入了我的阅读清单。感谢您在Python学习中的出色表现。类列表(对象):
不会出现在列表
类的实际定义中的任何地方<代码>类列表(对象)
出现在帮助(列表)
输出中,它可能会出现在PyCharm伪源代码或类似的东西中,但是在C@user2357112中。谢谢,很好的一点,我会添加进去。但列表只继承对象仍然是事实;由于是python对象,谢谢你,我的朋友。非常有趣的是,Python类并不仅仅遵循概念继承树。但是你能告诉我传递的意思吗?我不会说英语,所以这让我有点困惑。@flakes谢谢,你编辑的答案更清楚。但这也给我带来了更多的问题。为什么您的代码实现了子类钩子
,而不是子类检查
,什么是检查方法
?“我说得有道理,我很感激。”“请知道,我真的很感激你做出了一个没有错误、更清晰的回答。我的Python有所改进。非常感谢:)
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