2016-07-17 7 views
8

List ist eine Unterklasse von Sequence:ist List [str] keine Unterklasse der Sequenz [str]

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

aber List[str] ist keine Unterklasse von Sequence[str]:

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

Warum?

+1

Warum sollte es sein? 'List [str]' und 'Sequence [str]' sind wie Instanzen; spezifische Formen des generischen Typs. 'list()' ist auch keine Unterklasse von 'abc.Sequence()'. –

+0

Oder anders ausgedrückt: * Was nützt * eine IS-A-Beziehung zwischen 'List [str]' und 'Sequence [str]' beim Annotieren? –

Antwort

1

Welchen Nutzen würde eine IS-A-Beziehung zwischen List[str] und Sequence[str] hat, wenn mit Anmerkungen versehen?

Dies ist der wichtigste Punkt zu entfernen. Die Überprüfung, ob ein Typ ein Subtyp eines anderen Typs ist, ist im Allgemeinen nicht das, was Sie tun sollten, während Sie Ihren Code mit Anmerkungen versehen. Dies ist in der Regel etwas, was bemerkt wurde und ist der Grund, warum es eine Debatte über the nuking of __subclasscheck__ gibt.

Als Mark Shannon states in a comment:

Es ist sinnvoll zu prüfen, ob ein Typ ein Subtyp von einem Typ ist, aber das ist die Aufgabe eines statischen checker und gehört nicht in der Typisierung Modul.

So oder so, die Kontrollen sind all made in GenericMetas __subclasscheck__, die Metaklasse für generische Typen

Wie ist, ist die derzeitige Umsetzung stärker auf Fälle, in denen der Behälter Typ ähnlich ist, aber deren Unter scripted Typen unterscheiden sich, in dieser In diesem Fall werden Prüfungen durchgeführt, abhängig davon, ob die untergeordneten Typen covariant or contravariant sind. weder Zum Beispiel sind List Typen, die als solche für eine subtype Beziehung Überprüfung mit:

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

false zurück. Für Sequenzen sind die Typen covariant, als solche, die folgenden Ausbeuten True:

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

Auf der anderen Seite, für Typen ohne bestimmten Typen (wie in Ihrem ersten Fall):

issubclass(List, Sequence) 

__subclasscheck__ in GenericMeta wird delegate zu __subclasscheck__ in ABCMeta wo es True auswerten wird.

Schließlich, wenn die beiden Typen verschieden sind, wie in:

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

und der Basisklasse in der issubclass call is an instance of GenericMeta wird False zurückgegeben; Diese Bedingung ist für die meisten Typen in typing erfüllt.

Was auch immer der Fall ist, es ist erwähnenswert, dass dies in einer zukünftigen Version möglicherweise nicht existiert, oder sein Verhalten könnte völlig anders sein; Das Modul ist noch vorläufig.

Verwandte Themen