TypeChecking para una función que devuelve Ninguno
Considere la implementación recursiva de la función factorial:
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))
Estoy usando mypypara la verificación de tipos estáticos. Me arroja el siguiente error:
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)
Intenté usar Optionalsegún esta pregunta de stackoverflow. Pero no parece funcionar. ¿Alguna sugerencia?
Preguntas -
- ¿Cómo especificar el tipo de retorno cuando la función regresa
None? - Me parece un poco sorprendente que mypy haya podido imaginar una situación en la que podría ocurrir la multiplicación entre
inty .NonePor ejemplo, si eliminointel argumento val y llamo a la función factorial con un flotante, podría arrojar dicho error.
Respuestas
MyPy tiene razón en que la función no está bien escrita. La firma de la función es (int) -> Optional[int], por lo que val*factorial(val-1) posiblemente sea errónea. Eso Nonesolo ocurre para información de val < 0tipo no estático.
En lugar de regresar Nonepor una entrada no válida, genere una excepción. Esto hace que la función esté estáticamente bien tipada, sin eliminar el manejo de errores.
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)
Si se requiere regresar Nonepor alguna razón, anote explícitamente que la expresión es sólida y no necesita verificación.
def factorial(val: int) -> int:
if val<0:
return None
if val==0:
return 1
return val*factorial(val-1) # type: ignore