[英]Solving inheritance contradictions among abc.Sequence, abc.Hashable and list in Python
我使用的是版本3.6.3
我正在研究Python collections.abc
在類之間的繼承關系。 我在list
, Sequence
和Hashable
找到了一些相互矛盾的遺傳
就像你已經知道的那樣,
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
繼承A
和C
繼承B
,則C
必須繼承A
C
的傳遞超類集合將是A
, B
和Object
,直接超類是B
在Python中,我們偏離了這個概念。 正如您所指出的, Sequence
是Hashable
, list
是Sequence
,但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.