Annotazione del tipo restituito void Python


108

In python 3.x, è comune utilizzare l'annotazione del tipo di ritorno di una funzione, come ad esempio:

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

Qual è l'annotazione corretta per il tipo "void"?

Sto valutando 3 opzioni:

  1. def foo() -> None:
    • non logico IMO, perché Nonenon è un tipo,
  2. def foo() -> type(None):
    • utilizzando la migliore sintassi che conosco per ottenere NoneType,
  3. def foo():
    • omettere le informazioni sul tipo restituito esplicito.

L'opzione 2. mi sembra la più logica, ma ho già visto alcune istanze di 1.


11
FWIW, Python non ha funzioni con voidtipo restituito. Qualsiasi funzione (o ramo in una funzione) senza un esplicito returntornerà None. Presumo che l'OP lo capisca, questo commento è principalmente a beneficio dei futuri lettori ...
PM 2Ring

Bene, questa domanda non è così popolare come "perché la mia funzione restituisce None in Python?" (Ho creato questa domanda), quindi probabilmente la maggior parte dei lettori conosce già il comportamento predefinito. Il dilemma 1 contro 2 è risolto nella risposta. Ma per quanto riguarda 3? Per le "procedure" preferirei effettivamente l'opzione 3, senza inutili disordine (dopotutto, questa funzione non restituisce nulla).
Tomasz Gandor

@TomaszGandor D'accordo. Quando una funzione o un metodo non contiene un'istruzione return, non è necessario specificarne il tipo restituito.
Jeyekomon

Risposte:


121

Questo è direttamente dalla documentazione PEP 484 - Type Hints :

Quando viene utilizzata in un suggerimento sul tipo, l'espressione Noneè considerata equivalente a type(None).

E, come puoi vedere, la maggior parte degli esempi utilizza Nonecome tipo di ritorno.


22
Per chiarire, scegli l'opzione 1 sopra.
Adam Nelson


12
@asmaier secondo questa domanda che cita PEP 484 - Il tipo Suggerimenti NoReturn tipo viene utilizzato "... per annotare funzioni che non tornano mai normalmente. Ad esempio, una funzione che solleva incondizionatamente un'eccezione ..."
Rodrigo Laguna

38

TLDR: l'equivalente idiomatico di voidun'annotazione di tipo restituito è -> None.

def foo() -> None:
    ...

Questo corrisponde a quello di una funzione senza returno solo un nudo returnrestituisce None.

def void_func():  # unannotated void function
    pass

print(void())  # None

L'omissione del tipo restituito non significa che non sia presente alcun valore restituito. Secondo PEP 484 :

Per una funzione selezionata, l'annotazione predefinita per gli argomenti e per il tipo restituito è Any.

Ciò significa che il valore è considerato tipizzato dinamicamente e supporta staticamente qualsiasi operazione . Questo è praticamente il significato opposto di void.


I suggerimenti sui tipi in Python non richiedono strettamente i tipi effettivi. Ad esempio, le annotazioni possono utilizzare stringhe di nomi di tipo: Union[str, int], Union[str, 'int'], 'Union[str, int]'e diverse varianti sono equivalenti.

Allo stesso modo, l'annotazione di tipo Noneè considerata significare "è di NoneType". Questo può essere utilizzato non solo per i tipi di reso, anche se lo vedrai più spesso lì:

bar : None

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

Questo vale anche per i tipi generici. Ad esempio, è possibile utilizzare Nonein Generator[int, None, None]per indicare che un generatore non accetta o restituisce valori.


Anche se PEP 484 suggerisce questo Nonemezzo type(None), non dovresti usare la seconda forma esplicitamente. La specifica del suggerimento sul tipo non include alcuna forma di type(...). Questa è tecnicamente un'espressione di runtime e il suo supporto dipende interamente dal controllo del tipo. Il mypyprogetto sta considerando di rimuovere il supporto per type(None)e rimuoverlo anche da 484.

O forse dovremmo aggiornare PEP 484 per non suggerire che type(None)è valido come tipo, ed Noneè l'unica ortografia corretta? Ci dovrebbe essere uno - e preferibilmente solo uno - modo ovvio per farlo ecc.

--- JukkaL, 18 maggio 2018


4
Enorme shoutout per aver spiegato perché la terza opzione in realtà non è affatto una funzione void.
никта
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.