🗃️

Python 型ヒント 入門

2022/03/26に公開

はじめに

Python ではオプションで型ヒントをサポートしてます。
Python は動的型付け言語のため、明示的に型を書かなくても動作します。

以下の関数はPythonのコードとしてなに1つ問題なく動作します。

get_full_name.py
def get_full_name(first_name, last_name):
    full_name = first_name.title() + " " + last_name.title()
    return full_name

print(get_full_name("john", "doe"))

ですが、このコードはいかに高機能なエディターを使っても、 first_name = first_name. と打った後に、 文字列型のメソッド名を忘れてしまったら、エディターのオートコンプリート機能は何の役にも立たないでしょう。(エディターは Ctrl+Space 補完候補を表示します)

ですが、型ヒントを書くことでエディターによるサポートを最大限に受けることができます。
型ヒントはPythonを使い始めた初心者やプログラム自体をあまり書いたことがない人ほど、その効果の恩恵を受けると思うので、初心者の方にも型ヒントをきちんと利用することをおすすめします

なぜなら、オブジェクトのメソッドなどを忘れてしまっても(文字列のメソッドを忘れても)、エディターが教えてくれるからです

それでは、型ヒントの書き方を学んでいきましょう。

型ヒントのための初期設定

静的型チェック

まずは、型ヒントにしたがってコードを書いているかを確認するためのツールを導入します。

bash
pip install mypy

VSCodeへ型チェックツールを導入

VSCodeを使って、Pythonを書きたい方は以下の記事を元に初期設定を行ってください。
※ 日本語化などの設定については、こちらを参考に実施してください。

https://zenn.dev/karaage0703/books/80b6999d429abc8051bb

VSCode の初期設定と先ほどの mypy のインストールが終わっていれば、 VSCode への mypy の導入はとても簡単です。拡張機能のインストール方法にもあるとおり、左側のアクティビティーバーからExtension(拡張機能)ボタンをクリックして、拡張機能の一覧画面が表示されます。

検索窓に以下を入力してください。

ms-python.python

表示された Python の拡張機能を インストール ボタン をクリックして、インストールしてください。

インストールには、時間がかかります。先程インストールした拡張機能は Microsoft が公式に提供して Python 用の開発環境の詰め合わせみたいなものになります。インストールが完了すると以下のように、いろいろインストールされていると思います。

これでインストールは完了しました。後は、機能を有効化すれば完了です。
機能を有効化するにはsettings.jsonに設定を追加すれば大丈夫です。

settings.json の開き方はOSによってことなります。
以下のショートカットキー押下で、検索窓が表示されます。

  • Windows または Linux: Ctrl+Shift+P または F1
  • Mac: ⇧ ⌘ P または F1

検索窓が表示されたら、以下の様に入力してください。

> settings.json

すると、3つくらい候補が出てくると思いますが、その中から 基本設定: 設定 (JSON) を開く を選んでください。初期状態だと以下のようなファイルが開くと思います。

settings.json
{
}

以下のように修正してください。

settings.json
{
  "python.linting.mypyEnabled": true,
}

これで、VSCode への mypy の導入が完了しました。

先程の拡張機能に付属する Pylance の型チェック機能を有効化するには、以下のように設定を追加してください。 設定可能な値は、 basic または strict または off の3つです。

settings.json - pylanceも有効化する場合
{
  "python.linting.mypyEnabled": true,
  "python.analysis.typeCheckingMode": "basic",
}
VSCodeに拡張機能を入れると受けれるメリット

先程インストールした拡張機能には、mypy以外にも恩恵を受けられます。
例えば IntelliSense はもっとも大きな恩恵の1つと思います。

こちらは初期状態のVSCodeですが、first_nameと打って Ctrl + Space を打つとなにか入力の補助をしようとしてくれていますが、実際には同じファイル内の文字を羅列しているだけで何の役にも立ちません。

初期状態のVSCode

では、拡張機能をインストールした後の状態で確認してみましょう。こちらも first_name.と打った後は、役に立たなさそうですが、その前の first と打った時点では、多くのヒント与えてくれています。

拡張機能インストール後

これ以外にも、ファイル保存時に自動で blackautopep8 などが走り、コードを整形(見やすく)してくれる機能があります。初期状態では基本 OFF になっています。こちらの記事などを参考にしてください。

VSCodeにmypyが入っていると?

VSCodeに mypy のサポート機能が入っていると以下のように入力ミスがあった時に教えてくれます。
これは極端な例ですが、例えば関数の呼び出し時の引数の型が間違っている場合なども教えてくれます。

有効になっている

有効になっていない状態で、試してみると何もエラーが発生しないので、将来的に意図しないエラーが発生するかもしれません。

有効になっていない

型チェックの実行

mypy で型チェックする準備が整ったら以下のようにコマンドを実行します。
以下は、appディレクトリ以下のファイル型チェックを行います。

bash
$ mypy sample.py
Success: no issues found in 1 source file

型チェックの無効化

どうしても依存するパッケージ等の問題などで、型ヒントをクリアできない場合は、以下のようにコメントすることで、無効化できます。
明示的にエラーとなっている理由やエラーコードを記載して置くことで次回の更新時の助けになります。

このコメントは1行のみエラーを無視します。

mypyのエラー回避方法
問題のあるコード # type: ignore

VSCodeご利用の方で、Pylance の型チェック機能を有効にしている場合は、以下のようにして型チェックを回避することができます。このコメントはファイル内すべてで同じエラー名称を無視します。書き方としては # pyright: エラー名称=false

以下が、Pylanceのエラー画面ですが、ピンクの枠で囲んでいる箇所(青いリンク文字)が エラー名称 になります。このエラー名称をコピーして利用します。

pyrightのエラー回避
# pyright: reportGeneralTypeIssues=false

型ヒントの使い方

型を追加する

それでは、実際に型ヒントの書き方を見ていきましょう。はじめに書いたバージョンから1行だけ修正してみます。

get_full_name.py
-def get_full_name(first_name, last_name):
+def get_full_name(first_name: str, last_name: str):
    full_name = first_name.title() + " " + last_name.title()
    return full_name

print(get_full_name("john", "doe"))

最初の行の関数の引数の箇所が変わっています。これはデフォルト値を設定しているわけではなく、型ヒントです。
型ヒントは追加しても実行には何も影響を与えません。 しかし、先程のように関数を書いている途中でメソッド名がわからなくなっても大丈夫です。

型ヒントを記載してあげているので、first_namestr 型であるとエディターが認識し、 str 型のオブジェクトのメソッドを表示してくれました。

型ヒントの書き方

変数

変数では以下のように型ヒントを書きます。

sample.py
変数名: 型名
変数名: 型名 =

型ヒントのみを書くことができますが、初期化しない状態で利用しようとすると
NameErrorが発生します。

標準的なPythonの型

sample.py
item_1: str
item_2: int
item_3: float
item_4: bool
item_5: bytes

list

python3.6以上の場合は以下のよう書きます。
大文字で始まるListを利用します。

python3.6以上
from typing import List

item: List[str]

python3.9以上の場合は以下のように書きます。
builtins.list が使えるようになりした。

python3.9以上
item: list[str]

上記の2つは書き方は違いますが、意味はどちらも str 型の要素を持つ リストであることを明示しています。

tuple と set

python3.6以上の場合は以下のよう書きます。
大文字で始まるTupleを利用します。

python3.6以上
from typing import Tuple

item_t: Tuple[str, int, str]
item_s: Set[int]

python3.9 以上の場合は以下のように書きます。
builtins.tuple と builtins.set が使えるようになりした。

python3.9以上
item_m: tuple[str, int, str]
item_s: set[int]
  • 変数 items_t は int, int, str の 3 つの項目からなる タプル であることを明示しています
  • 変数 items_s は 各項目は int 型の セット であることを明示しています

dict

python3.6以上の場合は以下のよう書きます。
大文字で始まるDictを利用します。

python3.6以上
from typing import Dict

item: Dict[str, int]

python3.9 以上の場合は以下のように書きます。
builtins.dict が使えるようになりした。

python3.9以上
item: dict[str, int]

上記の2つは書き方は違いますが、意味はどちらも str 型のキーと int 型のアイテムを持つ 辞書であることを明示しています。

関数/メソッド

関数では以下のように型ヒントを書きます。

def sample(引数名: 型名, 引数名: 型名, 引数名: 型名, ...) -> 戻り値の型:
    return 戻り値

戻り値の方は明示的に記載しないでも、エディターがサポートしてくれる場合もありますが、明示的に書いてあげることでコードの入力を助けてくれます。

引数に int型とfloat型の値を取り、戻り値にfloat型の値を返す関数

sample.py
def sample1(item_1: int, item_2: float) -> float:
    return item_1 * item_2

戻り値がない場合

sample.py
def sample2(item_1: int, item_2: float) -> None:
  print(item_1 + item_2)

lambda

lambda 式では以下のように型ヒントを書きます。

from typing import Callable

zf2: Callable[[int], str] = lambda s: str(s).zfill(2)

ユーザー定義クラス

クラスでは以下のように型ヒントを書きます。

sample.py
class Curry:
    beef: int
    onion: int
    potato: int
    carrot: int
    roux: int
    rice: int

    def __init__(self, beef: int, onion: int, potato: int, carrot: int, roux: int) -> None:
        self.beef = beef
        self.onion = onion
        self.potato = potato
        self.carrot = carrot
        self.roux = roux

curry: Curry = Curry(beef=250, onion=400, potato=230, carrot=100, roux=115)

Union 複合型

Unionは「いずれかの型」を表現するためのものです。
例えば str型またはint型を表すようなものは以下のように書きます。

python3.6以上
from typing import Union

def process_item(item: Union[int, str]):
  print(item)
python3.10以上
def process_item(item: int | str):
  print(item)

Optional

Optionalは str のような型を持つ、または None であることを表現するためのものです。実質的は Union[str, None] と同義です。

python3.6以上
from typing import Optional

item: Optional[str]
python3.10以上
item: str | None

記事を更新しました。

  • 20220328: 結構読まれているみたいなので、「VSCodeへ型チェックツールを導入」と「lambda」を追加しました。合わせて誤字脱字の修正をしました。

記事追加

Discussion