TypeChecking per una funzione che restituisce None
Considera l'implementazione ricorsiva della funzione fattoriale -
from typing import Optional
def factorial(val: int) -> Optional[int]:
if val<0:
return None
if val==0:
return 1
return val*factorial(val-1)
if __name__ == "__main__":
print(square_root(3))
Sto usando mypy
per il controllo del tipo statico. Mi genera il seguente errore:
type-hints.py:8: error: Unsupported operand types for * ("int" and "None")
type-hints.py:8: note: Right operand is of type "Optional[int]"
Found 1 error in 1 file (checked 1 source file)
Ho provato a utilizzare Optional
come da questa domanda StackOverflow. Ma non sembra funzionare. Eventuali suggerimenti?
Domande -
- Come specificare il tipo restituito quando la funzione restituisce
None
? - Mi sembra un po' sorprendente che mypy sia stata in grado di immaginare una situazione in cui potrebbe verificarsi la moltiplicazione tra
int
e .None
Ad esempio, se rimuovoint
l' argomento val e chiamo la funzione fattoriale con un float, potrebbe generare tale errore.
Risposte
MyPy ha ragione sul fatto che la funzione non è ben tipizzata. La firma della funzione è (int) -> Optional[int]
, rendendola val*factorial(val-1)
eventualmente errata. Ciò None
si verifica solo per informazioni val < 0
di tipo non statico.
Invece di restituire None
un input non valido, solleva un'eccezione. Ciò rende la funzione staticamente ben tipizzata, senza rimuovere la gestione degli errori.
def factorial(val: int) -> int:
if val<0:
raise ValueError("factorial() not defined for negative values")
if val==0:
return 1
return val*factorial(val-1)
Se per qualche motivo è necessario restituire None
, annotare esplicitamente che l'espressione è valida e non necessita di controllo.
def factorial(val: int) -> int:
if val<0:
return None
if val==0:
return 1
return val*factorial(val-1) # type: ignore