簡體   English   中英

解決abc.Sequence,abc.Hashable和Python中的列表之間的繼承矛盾

[英]Solving inheritance contradictions among abc.Sequence, abc.Hashable and list in Python

我使用的是版本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 (意思是'你不能' 哈希(some_list) ')

issubclass(list, Hashable)


False

我認為這種繼承是矛盾的。 我完全理解list是可變的因為我已經使用了數百次list但是繼承關系圖不支持這個概念。 我錯了什么或錯過了什么?

我等你的adivce。 謝謝。

所以它實際上是一個有趣的設計特性,但Python子類實際上並不需要是可傳遞的。 Google定義的傳遞:

“如果特征在序列的連續成員之間適用,則它也必須適用於按順序排列的任何兩個成員。例如,如果A大於B,並且B大於C,則A大於C.”

對於繼承是可傳遞的語言,例如Java,如果B繼承AC繼承B ,則C必須繼承A C的傳遞超類集合將是ABObject ,直接超類是B

在Python中,我們偏離了這個概念。 正如您所指出的, SequenceHashablelistSequence ,但list不是Hashable 實際上,list並不直接繼承任何東西(除了每個python類繼承的object

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

在Python中,您可以使用元類實用程序中的__subclasscheck____subclasshook__來使內置方法issubclass做有趣的事情。 元類是一種高級語言功能,用於修改有關類如何操作的基本規則(修改issubclass如何工作是一個很好的例子) 在抽象基類metaclass ABCMeta__subclasscheck__方法將在類上調用__subclasshook__方法(如果已定義)。 您可以在這里閱讀有關用途精彩答案

某些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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM