Wie kommentiere ich Typen mehrerer Rückgabewerte?


105

Wie benutze ich Typhinweise, um eine Funktion zu kommentieren, die eine zurückgibt Iterable, die immer zwei Werte liefert: a boolund a str? Der Hinweis Tuple[bool, str]ist nah, außer dass er den Rückgabewerttyp auf ein Tupel beschränkt, nicht auf einen Generator oder einen anderen iterierbaren Typ.

Ich bin größtenteils neugierig, weil ich eine Funktion kommentieren möchte, mit der foo()mehrere Werte wie folgt zurückgegeben werden:

always_a_bool, always_a_str = foo()

Normalerweise funktioniert so foo()etwas wie return a, b(was ein Tupel zurückgibt), aber ich möchte, dass der Typhinweis flexibel genug ist, um das zurückgegebene Tupel durch einen Generator oder eine Liste oder etwas anderes zu ersetzen.



3
@ StevenM.Vascellaro Dies ist kein Duplikat dieser Frage
TWR Cole

Antworten:


143

Sie geben immer ein Objekt zurück. using gibt return one, twoeinfach ein Tupel zurück.

Also ja, -> Tuple[bool, str]ist völlig richtig.

Nur mit dem TupleTyp können Sie eine feste Anzahl von Elementen mit jeweils einem bestimmten Typ angeben . Sie sollten wirklich immer ein Tupel zurückgeben, wenn Ihre Funktion eine feste Anzahl von Rückgabewerten erzeugt, insbesondere wenn diese Werte bestimmte, unterschiedliche Typen sind.

Für andere Sequenztypen wird eine Typspezifikation für eine variable Anzahl von Elementen erwartet , daher typing.Sequenceist dies hier nicht geeignet. Siehe auch Was ist der Unterschied zwischen Listen und Tupeln?

Tupel sind heterogene Datenstrukturen (dh ihre Einträge haben unterschiedliche Bedeutungen), während Listen homogene Sequenzen sind. Tupel haben Struktur, Listen haben Reihenfolge.

Das Typ-Hinweis-System von Python folgt dieser Philosophie. Derzeit gibt es keine Syntax, um eine Iterable mit fester Länge anzugeben, die bestimmte Typen an bestimmten Positionen enthält.

Wenn Sie angeben müssen , dass eine iterable Datei ausreicht, können Sie am besten Folgendes tun:

-> Iterable[Union[bool, str]]

An diesem Punkt kann der Aufrufer Boolesche Werte und Zeichenfolgen in beliebiger Reihenfolge und unbekannter Länge (zwischen 0 und unendlich) erwarten .


2
Die Sprachspezifikation ermöglicht die Rückgabe anderer Iterables. foo()könnte yield True; yield "blah"und a, b = foo()würde noch funktionieren. Oder foo()könnte eine Liste zurückgeben. Ich habe meine Frage umformuliert, um deutlich zu machen, dass ich daran interessiert bin, ein beliebiges iterierbares, kein Tupel anzudeuten.
Richard Hansen

2
@RichardHansen: Ich habe die PEPs und die Dokumentation von typingund mypyweitere 2 Mal seit dem Posten erneut überprüft . Ich bin ziemlich sicher, dass ich nichts verpasst habe. Das heißt, es gibt hier auf SO mehrere Stammgäste mit viel Erfahrung mit Python-Hinweisen, die nicht zögern, mich zu korrigieren, wenn sich herausstellt, dass sie falsch sind, oder eine bessere Antwort veröffentlichen.
Martijn Pieters

19
Ich musste hinzufügen, from typing import Tupledamit die Tupel-Annotation funktioniert.
PHPirate

3
@PHPirate: Ja, und Sie müssten dasselbe für Iterableund tun Union. Da wir hier über ihre spezifische Verwendung sprechen, ist der Import impliziert.
Martijn Pieters

4
@MartijnPieters, danke für eine großartige Antwort, aber ich denke, der Kommentar von PHPirate ist es wert, in Ihre ursprüngliche Antwort umgewandelt zu werden.
Tim Mironov
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.