So geben Sie mithilfe von Typhinweisen mehrere Rückgabetypen an

204

Ich habe eine Funktion in Python, die entweder a booloder a zurückgeben kann list. Gibt es eine Möglichkeit, die Rückgabetypen mithilfe von Typhinweisen anzugeben?

Ist dies beispielsweise der richtige Weg, dies zu tun?

def foo(id) -> list or bool:
      ...
Yahya Uddin
quelle
5
Wie kommt man zu einer Liste oder einem Booleschen Wert?
Padraic Cunningham
11
@ PadraicCunningham Vielleicht ist die Implementierung, ich sende Ihnen meine ID, Sie senden mir entweder eine Liste oder einen Booleschen Wert : D
Bhargav Rao
wahrscheinlich ist das eine schwache Umsetzung
Sławomir Lenart
@ PadraicCunningham Polymorphismus. Wenn Ihre Funktion eine Überprüfung der Eingabe durchführt, möchten Sie einen Booleschen Wert erhalten, wenn Sie eine Variable eingeben, oder eine Liste von Booleschen Werten, wenn Sie eine Liste von Variablen eingeben.
Guimoute

Antworten:

281

Aus der Dokumentation

Klasse typing.Union

Unionstyp; Union [X, Y] bedeutet entweder X oder Y.

Daher ist der richtige Weg, mehr als einen Rückgabedatentyp darzustellen,

from typing import Union


def foo(client_id: str) -> Union[list,bool]

Beachten Sie jedoch, dass die Eingabe nicht erzwungen wird. Python bleibt weiterhin eine dynamisch typisierte Sprache. Die Anmerkungssyntax wurde entwickelt, um bei der Entwicklung des Codes zu helfen, bevor er in die Produktion freigegeben wird. Wie in PEP 484 angegeben, "findet zur Laufzeit keine Typprüfung statt."

>>> def foo(a:str) -> list:
...     return("Works")
... 
>>> foo(1)
'Works'

Wie Sie sehen können, übergebe ich einen int-Wert und gebe einen str zurück. Das __annotations__wird jedoch auf die jeweiligen Werte eingestellt.

>>> foo.__annotations__ 
{'return': <class 'list'>, 'a': <class 'str'>}

Weitere Informationen zu Typhinweisen finden Sie in PEP 483 . Siehe auch Was sind Typhinweise in Python 3.5 ?

Bitte beachten Sie, dass dies nur für Python 3.5 und höher verfügbar ist. Dies wird in PEP 484 deutlich erwähnt .

Bhargav Rao
quelle
Gibt es ein Äquivalent in Python 3.4
Yahya Uddin
1
@YahyaUddin Nope - PEP 484 : '(.... Es ist nur für Python3.5 abwärts.
Bhargav Rao
1
@ YahyaUddin Sehr überraschend. Meinen Sie Funktion Anmerkungen durch Zufall?
Bhargav Rao
2
Also lass mich sehen, ob ich das habe. Python 3.4 verfügt über Funktionsanmerkungen, die nichts anderes als Anmerkungen ausführen, die NICHT erzwungen werden. In Python 3.5 ist dies jedoch eine tatsächliche Typprüfung.
Yahya Uddin
1
@ BhargavRao, tut mir leid! Ich fand es einfach zu wichtig, in den Kommentaren zu bleiben.
Bobort
26

Die Aussage def foo(client_id: str) -> list or bool:bei der Auswertung entspricht def foo(client_id: str) -> list: und wird daher nicht das tun, was Sie wollen.

Die native Art, einen Hinweis vom Typ "entweder A oder B" zu beschreiben, ist Union (dank Bhargav Rao):

def foo(client_id: str) -> Union[list, bool]:

Ich möchte nicht der Typ "Warum willst du das überhaupt tun?" Sein, aber vielleicht ist es nicht das, was du willst, wenn du zwei Rückgabetypen hast:

Wenn Sie einen Bool zurückgeben möchten, um einen speziellen Fehlerfall anzuzeigen, sollten Sie stattdessen Ausnahmen verwenden. Wenn Sie einen Bool als speziellen Wert zurückgeben möchten, ist eine leere Liste möglicherweise eine gute Darstellung. Sie können auch angeben, dass mit Nonezurückgegeben werden könnteOptional[list]

Felk
quelle
6
Es gibt Anwendungen, bei denen die Rückgabe mehrerer Typen das sein kann, was Sie möchten: Zum Beispiel, wenn Sie einen von mehreren Untertypen, aber keine anderen Untertypen zurückgeben müssen, oder wenn Sie versuchen, Daten zu verarbeiten und das Rohformular zurückgeben möchten, wenn die Verarbeitung nicht erfolgt ist nicht verfügbar. Wenn Sie Legacy-Code verpacken, kann dies sehr nützlich sein, da es den Aktualisierungsprozess erleichtert und / oder unangenehme Stellen erkennt.
Nathaniel Ford
Die Ausnahmen und die leere Listenidee waren ebenfalls hilfreich. danke
Yahya Uddin
20

Falls jemand hier gelandet ist, um zu erfahren, wie Typen mit mehreren Rückgabewerten angegeben werden können, verwenden Sie Tuple[type_value1, ..., type_valueN]

from typing import Tuple

def f() -> Tuple[dict, str]:
    a = {1: 2}
    b = "hello"
    return a, b

Weitere Informationen: https://code-examples.net/en/q/2651e60

Anton Khodak
quelle