Python Typ-Hinweise: die Angabe eines Typs aus einer Liste von zahlen (int und/oder Schwimmer)?
Wie kann ich eine bestimmte Funktion kann eine Liste von zahlen, die kann ints oder floats?
Ich habe versucht, eine neue Art der Verwendung von Union in etwa so:
num = Union[int, float]
def quick_sort(arr: List[num]) -> List[num]:
...
Jedoch mypy nicht wie diese:
quickSortLomutoFirst.py:32: error: Argument 1 to "quickSortOuter" has
incompatible type List[int]; expected List[Union[int, float]]
Ist es ein Typ, der umfasst ints und floats?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die kurze Antwort auf deine Frage ist, solltest du entweder TypeVars oder Sequenz -- mit
List[Union[int, float]]
eigentlich wäre möglicherweise die Einführung eines bug in deinem code!Kurz gesagt, das problem ist, dass Listen sind invariante nach der PEP 484 type system (und in vielen anderen typesystems -- z.B. Java, C#...). Man versucht, diese Liste verwenden, als ob es kovariante statt. Sie können lernen, mehr über Kovarianz und Invarianz hier und hier, aber vielleicht ein Beispiel, warum dein code ist potentiell un-typesafe nützlich sein könnten.
Betrachten Sie den folgenden code:
Wenn Sie diesen code erlaubt, typecheck, wir nur brach unseren code! Jeder code beruht auf
foo
wird der genau TypList[int]
würde jetzt Pause.Oder genauer, obwohl
int
ist eine legitime SubtypUnion[int, float]
ist, bedeutet das nicht, dassList[int]
ist ein Subtyp desList[Union[int, float]]
oder Umgekehrt.Wenn wir ok sind, mit diesem Verhalten (wir sind ok mit
quick_sort
Entscheidung zu injizieren beliebige ints oder floats in das Eingabe-array), das Update manuell zu Annotierenfoo
mitList[Union[int, float]]
:Ist, erklären sich vor, dass
foo
trotz nur mit Ganzzahlen, ist auch gedacht, um enthalten Schwimmer als auch. Dies verhindert, dass uns von einer falschen Verwendung der Liste nachquick_sort
genannt wird, umgehen Sie das Problem insgesamt.In einigen Kontexten kann dies sein, was Sie tun möchten. Für diese Methode, obwohl, wahrscheinlich nicht.
Wenn wir nicht ok mit diesem Verhalten, und wollen
quick_sort
zu erhalten was auch immer Typen wurden ursprünglich in der Liste, die zwei Lösungen in den Sinn kommen:Die erste ist die Verwendung einer kovariante geben nicht auf "Liste" -- zum Beispiel,
Sequenz
:Es stellt sich heraus Reihenfolge ist mehr oder weniger ähnlich wie Listen, außer dass es unveränderlich (oder genauer gesagt, die Sequenz-API enthält keine Weise, dass Sie mutieren in der Liste). Auf diese Weise können wir sicher umschifft den Fehler hatten wir bis oben.
Die zweite Lösung ist, Ihr array genauer gesagt, und darauf bestehen, dass es muss enthalten alle int-Werte oder alle Schwimmer, erlauben und eine Mischung von beiden. Wir können dies tun, mit TypeVars mit Einschränkungen Wert:
Dies wird auch verhindern, dass wir aus versehen "mischen" von Typen wie hatten wir bis oben.
Ich würde empfehlen, mit dem zweiten Ansatz-es ist ein bisschen genauer, und verhindert, dass Sie verlieren Informationen über den genauen Typ eine Liste enthält, wie Sie führen Sie es durch Ihre quicksort-Funktion.
Vom PEP 484, die vorgeschlagene Art Tipps:
Nicht die Mühe mit der
Union
s. Just-stick zuSequence[float]
.Edit: vielen Dank an Michael für den Fang der Unterschied zwischen
List
undSequence
.