Annotation vom Typ Python void return

105

In Python 3.x wird häufig die Annotation einer Funktion vom Rückgabetyp verwendet, z.

def foo() -> str:
    return "bar"

Was ist die richtige Anmerkung für den Typ "void"?

Ich erwäge 3 Optionen:

  1. def foo() -> None:
    • nicht logische IMO, weil Nonekein Typ ist,
  2. def foo() -> type(None):
    • mit der besten Syntax, die ich kenne, um zu erhalten NoneType,
  3. def foo():
    • Lassen Sie explizite Informationen zum Rückgabetyp weg.

Option 2. scheint mir am logischsten zu sein, aber ich habe bereits einige Instanzen von 1 gesehen.

Tregoreg
quelle
9
FWIW, Python hat keine Funktionen mit voidRückgabetyp. Jede Funktion (oder Verzweigung in einer Funktion) ohne explizite Angabe returnwird zurückgegeben None. Ich
gehe
Nun, diese Frage ist nicht so beliebt wie "Warum gibt meine Funktion in Python None zurück?" (Ich habe mir diese Frage ausgedacht), daher kennen wahrscheinlich die meisten Leser das Standardverhalten bereits. Das Dilemma 1 gegen 2 ist in der Antwort gelöst. Aber was ist mit 3? Für "Prozeduren" würde ich eigentlich Option 3 ohne nutzlose Unordnung bevorzugen (schließlich gibt diese Funktion nichts zurück).
Tomasz Gandor
@TomaszGandor zustimmen. Wenn eine Funktion oder Methode keine return-Anweisung enthält, muss der Rückgabetyp nicht angegeben werden.
Jeyekomon

Antworten:

119

Dies ist direkt aus der Dokumentation zu PEP 484 - Type Hints :

Bei Verwendung in einem Typhinweis wird der Ausdruck Noneals äquivalent zu betrachtet type(None).

Und wie Sie sehen können, werden die meisten Beispiele Noneals Rückgabetyp verwendet.

AKS
quelle
21
Wählen Sie zur Verdeutlichung Option 1 oben.
Adam Nelson
6
Was ist mit dem NoReturn-Typ python.org/dev/peps/pep-0484/#the-noreturn-type ?
Asmaier
10
@asmaier gemäß dieser Frage, die PEP 484 - Type Hints zitiert, wird der NoReturnTyp "... verwendet, um Funktionen zu kommentieren, die niemals normal zurückkehren. Zum Beispiel eine Funktion, die bedingungslos eine Ausnahme auslöst ..."
Rodrigo Laguna
36

TLDR: Das idiomatische Äquivalent einer voidAnnotation vom Rückgabetyp ist -> None.

def foo() -> None:
    ...

Dies entspricht, dass eine Funktion ohne returnoder nur eine bloße returnBewertung ergibt None.

def void_func():  # unannotated void function
    pass

print(void())  # None

Das Weglassen des Rückgabetyps bedeutet nicht , dass kein Rückgabewert vorhanden ist. Gemäß PEP 484 :

Für eine aktivierte Funktion lautet die Standardanmerkung für Argumente und für den Rückgabetyp Any.

Dies bedeutet, dass der Wert als dynamisch typisiert betrachtet wird und jede Operation statisch unterstützt . Das ist praktisch die entgegengesetzte Bedeutung von void.


Typhinweise in Python erfordern nicht unbedingt tatsächliche Typen. Beispielsweise können für Anmerkungen Zeichenfolgen mit Typnamen : Union[str, int], verwendet werden Union[str, 'int'], 'Union[str, int]'und verschiedene Varianten sind äquivalent.

Ähnlich ist die Typanmerkung Nonegilt als verstanden „ist NoneType“. Dies kann nicht nur für Rückgabetypen verwendet werden, obwohl Sie es dort am häufigsten sehen werden:

bar : None

def foo(baz: None) -> None:
    return None

Dies gilt auch für generische Typen. Zum Beispiel können Sie verwenden , Nonein Generator[int, None, None]sich einen Generator , um anzuzeigen , nicht nehmen oder Werte zurückgeben.


Obwohl PEP 484 , die vorschlägt , NoneMittel type(None), Sie sollten nicht die letztere Form explizit verwenden. Die Type Hinting - Spezifikation ist nicht jede Form der type(...). Dies ist technisch gesehen ein Laufzeitausdruck, und seine Unterstützung liegt ganz bei der Typprüfung. Das mypyProjekt erwägt, die Unterstützung für type(None)484 zu entfernen und diese ebenfalls zu entfernen.

Oder sollten wir PEP 484 aktualisieren, um nicht vorzuschlagen, dass dies type(None)als Typ gültig ist und Nonedie einzig richtige Schreibweise ist? Es sollte einen - und vorzugsweise nur einen - offensichtlichen Weg geben, dies zu tun usw.

--- JukkaL, 18. Mai 2018

MisterMiyagi
quelle
3
Riesiger Ruf, um zu erklären, warum die dritte Option eigentlich überhaupt keine ungültige Funktion ist.
никта