2015-09-25 5 views
7

Ich spielte ein bisschen mit dem neuen Typ Hinting/Typing-Modul mit python3.5 versuchte einen Weg zu finden, zu bestätigen, ob der angedeutete Typ gleich dem eigentlichen Typ der Variable ist und stieß auf etwas, das mich eher überraschte.Warum wird isinstance ([1, 2, 3], List [str]) als wahr ausgewertet?

>>> from typing import List 
>>> someList = [1, 2, 3] 
>>> isinstance(someList, List[str]) 
True 

Fortsetzung meiner Suche einen Weg für die Suche nach eine Variable es angedeutet Art zu vergleichen habe ich auch schon versucht, diese:

>>> anotherList = ["foo", "bar"] 
>>> type(anotherList) is List[str] 
False 

der Lage wäre, jemand zu erklären, warum genau die ehemaligen auswertet auf True?

Und fortfahren, gibt es eine solide Möglichkeit, um zu überprüfen, ob der Typ einer Variablen einem Typ entspricht, der vom Typisierungsmodul kommt?

+2

Nun, zum einen sind 'type (x) ist a' und' isinstance (x, a) 'sind definitiv nicht das Gleiche. Ein Objekt kann eine Instanz vieler Typen sein (mit einer Vererbungshierarchie), aber "type (x)" gibt Ihnen nur seinen spezifischsten Typ. – BrenBarn

+0

Yup, ich bin mir dessen bewusst, nachdem ich es getestet habe. Ich hatte immer noch das Gefühl, es in meine Frage aufzunehmen, da es oft als Einstieg angeboten wird, wenn man etwas über Typvergleiche in Python fragt. – McMuffinton

+0

Was bedeutet '' '(['foo', 'bar']) == List [str]' '' evaluate to? –

Antwort

4

isinstance tut nicht wirklich PEP 484 Typüberprüfung. The documentation Noten dies nebenbei:

Im Allgemeinen isinstance() und issubclass() sollten nicht mit Typen verwendet werden.

Das typing Modul, sowie die collections.abc und abc Module es basiert auf, verwenden Sie umfangreiche __instancecheck__ and __subclasscheck__ Magie isinstance zu machen und issubclass vernünftig verhalten. Aber sie tun nicht genug, um deinen Fall zu unterstützen. Es ist auch nicht ihr Ziel, es zu unterstützen.

Gibt es eine gute Möglichkeit zu überprüfen, ob der Typ einer Variablen einem Typ entspricht, der vom Typisierungsmodul kommt?

Sie suchen nicht nach Typ Gleichheit. Wie Sie selbst festgestellt haben, ist der Typ [1, 2, 3]list, der nicht gleich zu List[str], noch zu List[int] ist. Sie suchen nach Typ Prüfung, die viel komplizierter ist.

Bedenken Sie:

def my_function(): 
    # ... 1000 lines of very complicated code ... 

print(isinstance(my_function, Callable[[], int])) 

Was würden Sie dieses Programm drucken erwarten? Sie können nicht erwarten, dass isinstance zur Laufzeit in my_function eingräbt und folgern, dass es immer int zurückgibt. Dies ist in Python nicht möglich. Sie benötigen entweder einen Zeitüberprüfungstester zum Kompilieren, der Zugriff auf die Struktur my_function hat, oder explizite Annotationen oder - höchstwahrscheinlich - beides.

+0

Vielen Dank für Ihre klare und prägnante Antwort.Ich verstehe sehr wohl, warum man nicht erwarten kann, dass eine Funktion herausfindet, ob eine andere Funktion immer eine Variable eines bestimmten Typs zurückgibt, aber ich könnte mir vorstellen, dass es irgendwie möglich wäre, _check_ zu überprüfen, wenn eine einzelne Variable einem Typ entspricht das Typisierungsmodul. Dies erfordert jedoch die manuelle Prüfung, ob jedes Element in einer Liste einen bestimmten Typ hat, der in Situationen mit großen Listen oder verschachtelten Typen (List [Dict [str, List [int]) einfach zu lange dauern würde, um machbar zu sein. Nochmals vielen Dank für Ihre Antwort! – McMuffinton

+1

@McMuffington Mein Punkt ist, dass 'my_function' genauso" eine einzelne Variable "ist wie Ihre' someList'. Wenn Sie nicht erwarten, den Typ von 'my_function' zur Laufzeit abzuleiten, gibt es keinen Grund, das von' someList' zu erwarten. –

+0

Was _are_ 'isinstance' und' issubclass' sollen dann tun? – brandonscript