为什么List[str]不是Sequence[str]的子类



> ListSequence 的子类:

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

List[str]不是Sequence[str]的子类:

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

为什么?

注释时,List[str]Sequence[str]之间的 IS-A 关系有什么用?

这是要带走的主要观点。检查一个类型是否是另一种类型的子类型通常不是在类型批注代码时应该做的事情。这通常是已经注意到的事情,也是为什么对__subclasscheck__进行核弹辩论的原因。

正如马克·香农(Mark Shannon(在评论中所说:

检查类型

是否是类型的子类型是有意义的,但这是静态检查器的工作,不属于类型模块。

无论哪种方式,检查都是在GenericMeta__subclasscheck__中进行的,泛型类型的元类

按原样,当前的实现更侧重于容器类型相似但其子脚本类型不同的情况,在这种情况下,将根据子脚本类型是协变还是逆变进行检查。例如,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)

GenericMeta __subclasscheck__将委托给ABCMeta __subclasscheck__,在那里它将评估为True

最后,如果两种类型不同,如下所示:

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

issubclass 调用中的基类是 GenericMeta 的实例,False返回;typing 中的大多数类型都满足此条件。

无论如何,值得一提的是,这在未来的版本中可能不存在,或者它的行为可能完全不同;该模块仍然是临时的。

最新更新