Python講座 / 型ヒントで引数と戻り値を示す

型ヒントは引数や戻り値に期待する型を、人や静的解析ツールへ伝えます。通常のPython実行で自動的に型を強制する仕組みではないため、外部入力の検証や変換とは区別します。

型の宣言を変換だと思わない

amount: intは整数を期待する記述で、値をintへ変換する操作ではありません。-> strは文字列の結果を期待する記述です。エディターや静的解析ツールは、不適切な呼び出しを探すためにこれを利用できます。

list[int]は整数のリスト、str | Noneは文字列または値がない状態を示します。この実習はPython 3.12以降を対象とします。注釈そのものを動的に調べるコードでは、使うバージョンの注釈評価の規則も確認してください。

実行時例外と検証テストは、try・except・else・finally・raiseで例外を扱うで扱う規則とつながります。

注釈と明示的な検査を比べる

hints.pyを保存し、仮想環境でpython hints.pyを実行します。

def format_amount(amount: int) -> str:
    if type(amount) is not int or amount < 0:
        raise ValueError("invalid amount")
    return f"{amount:,} KRW"

def find_name(names: dict[str, str], key: str) -> str | None:
    return names.get(key)

print(format_amount(8000))
print(find_name({"e1": "lunch"}, "missing"))
try:
    format_amount("8000")
except ValueError:
    print("rejected")

予想結果です。rejectedは型注釈ではなく、関数内で書いた検証によって表示されます。

8,000 KRW
None
rejected

必要に応じて静的解析を実行する

プロジェクトの環境へmypyを導入し、ファイルを解析できます。

python -m pip install mypy
python -m mypy hints.py

意図的に渡した文字列の引数は静的な型エラーとして報告され得ます。呼び出しを正すか、入力方針に沿って明示的に変換します。警告を消すためだけにすべてをAnyへ変えると、契約を示す利点が薄れます。

静的な確認を通っても、ファイルの存在、通信の成功、業務データの妥当性が保証されるわけではありません。

値がない場合と不正な値を扱う

find_nameはNoneを返すことがあります。文字列のメソッドを呼ぶ前に、その場合を処理します。実際のすべてのreturnと注釈を一致させ、呼び出し側が値の欠落を推測しなくて済むようにします。

外部JSONの文字列"8000"を変換して受け入れるか、拒否するかは型注釈だけでは決まりません。整数、負数、文字列、欠落の各場合について期待する結果を決めます。自動テストにすると、戻り値の型と検証経路を繰り返し確認できます。

上のhints.pyにはformat_amount("8000")という意図的な型エラーが既にあります。実行時はValueErrorを捕まえてrejectedを表示し、mypyは引数の型エラーとして報告します。この呼び出しを除いたコピーで静的検査の成功と比較します。型ヒントは外部入力検証の代わりではなく、検査メッセージはバージョンで異なります。

項目 動作
静的検査 注釈とコードの型関係を確認
実行時検証 外部の値・範囲・必須項目を確認

関連する公式リファレンス