これまで、あまりPythonに型の必要性を感じてなかったので、うっかりスルーしてきたのですが、改めて学んでみました。
Pythonで型ヒントの書き方
Pythonの型ヒントの使用例は以下の通りです。
# 変数に型ヒントを指定する
name: str = "Luca"
age: int = 22
# 関数に型ヒントを指定する
def greet(name: str, age: int) -> str:
return f"Hello, {name}({age})"
print(greet(name, age))
ListやDict型の型ヒント
ListやDict型の型ヒントを使うときは、typingモジュールを使います。
from typing import List, Tuple, Dict
# 関数に型ヒントを指定する
def list_to_str(items: List) -> str:
lines = ""
for it in items:
lines += it + '\n'
return lines
print(list_to_str(['a', 'b', 'c']))
静的型チェックをしたい時
実際のところ、型が間違っていても、型はあくまでもヒントであり、特にエラーが出るというわけではありません。以下は、List[str]を求める関数list_to_strを定義しましたが、List[int]型のリストを与えてもエラーは出ません。
from typing import List, Tuple, Dict
# 引数がList[str]を取ることを明示
def list_to_str(items: List[str]):
for it in items:
print(it)
# List[int]を指定したがエラーは出ない
list_to_str([10,20,30])
そこで登場するのが、静的型チェックを行うパッケージmypy
です。以下のようにして、mypyをインストールします。
$ python3 -m pip install mypy
そして、上記のプログラム「type_err.py」を以下のようにチェックします。すると、エラーを表示します。
$ mypy type_err.py
type_err.py:9: error: List item 0 has incompatible type "int"; expected "str" [list-item]
type_err.py:9: error: List item 1 has incompatible type "int"; expected "str" [list-item]
type_err.py:9: error: List item 2 has incompatible type "int"; expected "str" [list-item]
Found 3 errors in 1 file (checked 1 source file)
D
ユニークな型を定義して使う場合
typingのNewTypeを使うと、既存型を指定して、新たな型を定義できます。
from typing import NewType
# NewTypeを使って、型を定義
UserId = NewType('UserId', int)
ItemId = NewType('ItemId', int)
これを使うと、意図的に異なる意味や目的を持つデータを区別することができることです。
下記の例では、a_idなどという中途半端な変数名を使うことにしたため、UserIdとItemIdを間違えて関数を呼び出しています。
from typing import NewType
# NewTypeを使って、型を定義
UserId = NewType('UserId', int)
ItemId = NewType('ItemId', int)
# 引数が UserId を取ることを明示
def get_user_name(user_id: UserId) -> str:
if user_id == 1:
return 'Luca'
else:
return 'Unknown user'
# ItemId の変数を宣言
a_id: ItemId = 1
# UseIdを指定するべきところを間違えて ItemId を渡してしまう!!
print(get_user_name(a_id))
上記のプログラム、実行すると・・・正しく動いてしまいます。エラーは1ミリも出ません。
しかし、静的型チェックを行うと・・・下記のように正しくエラーを出してくれます。
$ mypy err.py
err.py:15: error: Incompatible types in assignment (expression has type "int", variable has type "ItemId") [assignment]
err.py:17: error: Argument 1 to "get_user_name" has incompatible type "ItemId"; expected "UserId" [arg-type]
Found 2 errors in 1 file (checked 1 source file)
Visual Studio Codeで型ヒントを活用するヒント
なお、VSCodeで型ヒントをもっと積極的に使うには、Python:Linterでmypyを選択すると良いです。
以下のように、型ヒントに沿ってVSCodeが間違いを指摘してくれるようになります。
まとめ - 型を付けるとなにが良いのか?
- 型をつけておくと、エディタやIDEを使う時に、入力補完が利くのでとても便利です。
- 型をつけると、mypyを使って静的型チェックが可能になって便利です。
- 型を付けると、コードの品質を向上させることが可能です。