Noneを返す関数のTypeChecking

Aug 23 2020

階乗関数の再帰的実装を検討してください-

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))

mypy静的型チェックに使用しています。それは私に次のエラーをスローします-

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)

私はこのstackoverflowの質問Optionalに従って使用してみました。しかし、それはうまくいかないようです。助言がありますか?

質問-

  1. 関数が戻るときに戻りタイプを指定するにはどうすればよいNoneですか?
  2. mypyintとの間の乗算Noneが発生する可能性がある状況を想像できたのは少し驚きのようです。例えば-私は削除した場合intのためにvalを引数とフロートとの階乗関数を呼び出し、それがこのようなエラーをスローする可能性があります。

回答

2 MisterMiyagi Aug 23 2020 at 03:01

MyPyは、関数が適切に入力されていないということは正しいです。関数のシグネチャはであり(int) -> Optional[int]、エラーのval*factorial(val-1) 可能性があります。これは静的な型情報Noneval < 0ない場合にのみ発生します。

None無効な入力を返す代わりに、例外を発生させます。これにより、エラー処理を削除することなく、関数が静的に適切に型指定されます。

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)

None何らかの理由で戻る必要がある場合は、式が適切であり、チェックする必要がないことを明示的に通知します。

def factorial(val: int) -> int:
    if val<0:
        return None
    if val==0:
        return 1
    return val*factorial(val-1)  # type: ignore