TypeChecking para uma função que retorna None
Considere a implementação recursiva da função fatorial -
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))
Estou usando mypypara verificação de tipo estático. Isso me dá o seguinte erro -
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)
Eu tentei usar Optionalde acordo com esta questão do stackoverflow. Mas não parece funcionar. Alguma sugestão?
Perguntas -
- Como especificar o tipo de retorno quando a função retorna
None? - Parece um pouco surpreendente para mim que mypy foi capaz de imaginar uma situação em que a multiplicação entre
inteNonepode ocorrer. Por exemplo - Se eu remover o argumentointfor val e chamar a função fatorial com um float, isso poderá gerar esse erro.
Respostas
MyPy está correto ao dizer que a função não está bem digitada. A assinatura da função é (int) -> Optional[int], tornando val*factorial(val-1) possivelmente errônea. Isso Noneocorre apenas para informações val < 0de tipo não estático.
Em vez de retornar Nonepara entrada inválida, gere uma exceção. Isso torna a função estaticamente bem tipada, sem remover o tratamento de erros.
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 retornar Nonefor necessário por algum motivo, anote explicitamente que a expressão é sólida e não precisa ser verificada.
def factorial(val: int) -> int:
if val<0:
return None
if val==0:
return 1
return val*factorial(val-1) # type: ignore