鬱猫のつぶやき

鬱猫が日々思っていることをつづります

Python 型アノテーション

はじめに

Python 3.5 から導入された型アノテーションについての自分用のメモになります。

アノテーション

Python は動的型付けの言語です。それに起因して、実行時に思わぬエラーに遭遇することが少なくありません。

実行時に遭遇するエラーをできるだけ最小にするために、最近の Python では型アノテーションをつけ、実行前に型の整合性が取れているのかを確認する機構が入っています。

具体的にコードで示しましょう。

import json
from typing import Dict


def hoge() -> str:
    return "hoge"


def int_to_str(i: int) -> str:
    return str(i)


def main() -> None:
    with open("test.json", "r") as fin:
        dat: Dict[str, str] = json.loads(fin.read())
    print(dat["a"])
    # print(dat[1]) # <-- index は str であるべきなのに、int になっている

    print(int_to_str(hoge())) # <-- hoge は str を返すが int_to_str の引数は int を受け取る

if __name__ == "__main__":
    main()

関数の宣言が少し変わっているのがわかると思います。

def int_to_str(i: int) -> str:
    return str(i)

上記は引数 i が int 戻り値が str になることを宣言しています。

引数、ローカル変数の方を指定する場合は変数のあとにコロン、そのあとに型をつければ OK です。 関数の戻り値の方を指定する場合は、関数宣言の後に -> type をつけます。

さて、これをそのまま実行するだけだと実行時にエラーが発生するだけで全く恩恵はありません。

Python では実行前に型の整合性が取れているのかチェックするプログラムが用意されています。それが mypy です。

mypy でチェック

pip で導入していない場合は、まず以下のコマンドで mypy を導入しましょう。

$ pip install mypy

さて、さっきの例を mypy で検査させてみましょう。test.py としてセーブして mypy の引数としてファイル名を指定します。

$ mypy test.py
test.py:19: error: Argument 1 to "int_to_str" has incompatible type "str"; expected "int"
Found 1 error in 1 file (checked 1 source file)

int_to_str の引数として int が期待されているけども、実際は str になっているとエラー出しているのがわかります。 確かに型の検査が実行前に行われていることが確認できますね。