2016-07-17 9 views
8

List подкласс Sequence:Почему Список [ул] не подкласс Sequence [ул]

>>> from typing import List, Sequence 
>>> issubclass(List, Sequence) 
True 

но List[str] не подкласс Sequence[str]:

>>> issubclass(List[str], Sequence[str]) 
False 

Почему?

+1

Зачем это должно быть? 'List [str]' и 'Sequence [str]' похожи на экземпляры; специфические формы родового типа. 'list()' также не является подклассом 'abc.Sequence()'. –

+0

Или иначе: * Какое использование * будет иметь отношение IS-A между 'List [str]' и 'Sequence [str]' при аннотации? –

ответ

1

Какое отношение имеет отношение IS-A между List[str] и Sequence[str] при аннотации?

Это главный момент, чтобы забрать. Проверка того, является ли тип подтипом другого типа, обычно не является чем-то, что вы должны делать, в то время как тип аннотирует ваш код. Это, как правило, то, что было замечено и является причиной того, что есть дебаты на the nuking of __subclasscheck__.

Как Марк Шеннон states in a comment:

имеет смысл проверить тип является ли подтип типа, но это задание статической проверки и не принадлежит в модуле набора текста.

В любом случае, чеки all made in GenericMetas __subclasscheck__, метакласс для общих типов

Как есть, текущая реализация более ориентирована на тех случаях, когда тип контейнера похож, но их суб-сценарии типа отличается, в этом case, проверки выполняются в зависимости от того, являются ли подстрочные типы covariant or contravariant. Например, List типов не являются ни, как таковой, проверка на subtype отношения с:

issubclass(List[bool], List[int]) # checks if bool == int 

возвращает ложь. Для последовательностей, типы ковариантны, как таковые, следующие выходы True:

issubclass(Sequence[bool], Sequence[int]) # checks if bool is a subclass of int 

С другой стороны, для типов без определенного типа (как в первом случае):

issubclass(List, Sequence) 

__subclasscheck__ в GenericMeta будет delegate до __subclasscheck__ in ABCMeta, где будет оцениваться True.

Наконец, если два типа различны, как в:

issubclass(List[str], Sequence[str]) 

и базового класса в issubclass call is an instance of GenericMeta, False возвращается; это условие выполняется для большинства типов в typing.

В любом случае стоит упомянуть, что это может не существовать в будущей версии или, его поведение может быть совершенно иным; модуль все еще является предварительным.