Python: 01. 型ヒント - ikymrkw/pydepot GitHub Wiki
型ヒントはオプション機能で、書かなくてもよいが、頑健でわかりやすいコードを書くためにはできるだけ使った方がよい。
型ヒントは静的・動的にチェック・強制されるわけではない。
プログラマーがコードそのものや doccomment を見て参考にするほか、
mypy などのツールや Visual Studio Code などの IDE が利用して型の不一致チェックや適切な補完を行う。
この解説が詳しい: 2021年度版Pythonの型ヒントの書き方 (for Python 3.9)
基本
最初に代入する際に、変数名の直後に : 型 という形式で記載する。
name: str = 'Alice'
age: int = 25
関数の仮引数にも変数と同様に付けられる。関数の戻り値は -> 型 という形式で記載する。戻り値がない場合は -> None とする。
def f() -> str:
return "dummy"
def g(a: int, b: int = 123) -> int:
return a + b
def do_something() -> None:
# do ...
型はユーザ定義のクラスでも構わない。
Any と Type
任意の型を受け付けたい/受け付けざるを得ない場合は typing.Any を指定する。
from typing import Any
def f(a: Any) -> Any:
...
型そのものを受け付ける/返す場合は typing.Type というジェネリクス(後述)を使う。
from typing import Type
def get_handler_class(a: str) -> Type[MyClass]:
...
前方参照
まだ読み込みが完了していない型・クラスを型ヒントに指定するには、型名を文字列リテラルで指定する。
典型的な用途は、自分自身を返したり受け取ったりするクラスのメソッド。
class TreeNode:
def get_parent(self) -> TreeNode: # TreeNode クラスが未完成なのでエラーになる
...
def get_parent2(self) -> "TreeNode": # これなら OK
...
コンテナ型(ジェネリクス)
list, tuple, dict のように、中に他の値を格納する(あるいはもっと一般的に、特定の型の値を扱う)クラスを指定するとき、単に list だけ指定してもあまり意味がない。
def f(names: list):
s: str = ''
for n in names:
s += n # この n の型は何???
そこで、コンテナ型の扱う型を記載する方法が用意されている。
def f(names: list[str]):
n = names[0] # n の型は str
list[str] # 全要素が str の list, 長さは自由
list[str, str] # 全要素が str で長さが 2 の list
tuple[str] # str 要素1つだけの tuple
tuple[str, ...] # 任意長の tuple
dict[str, int] # str -> int の dict
list でも tuple でもいいよ、という場合は、(後述するように Union[list, tuple] や list | tuple と書くこともできるが、)両者の親の型を指定したほうがよい。詳細は省くが、中身を変えずに見るだけであれば、 Collection またはその親の Iterable が list, tuple, dict の共通の親インタフェースなので、これらを使うとよい(どう使うかに依存する)。Sequence は list のみの親なので注意。
# 以上は Python 3.9 以降の話 (PEP-0585)。Python 3.8 以前では typing モジュールを使う。
from typing import List, Tuple, Dict
def f(names: List[str]):
n = names[0] # n の型は str
List[str] # 全要素が str の list, 長さは自由
List[str, str] # 全要素が str で長さが 2 の list
Tuple[str] # str 要素1つだけの tuple
Tuple[str, ...] # 任意長の tuple
Dict[str, int] # str -> int の dict
あるいは from __future__ import annotations を書けば 3.9 以降の書き方が使えるようになる。