Python 型ヒント 入門
はじめに
Python ではオプションで型ヒントをサポートしてます。
Python は動的型付け言語のため、明示的に型を書かなくても動作します。
以下の関数はPythonのコードとしてなに1つ問題なく動作します。
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を使い始めた初心者やプログラム自体をあまり書いたことがない人ほど、その効果の恩恵を受けると思うので、初心者の方にも型ヒントをきちんと利用することをおすすめします。
なぜなら、オブジェクトのメソッドなどを忘れてしまっても(文字列のメソッドを忘れても)、エディターが教えてくれるからです。
それでは、型ヒントの書き方を学んでいきましょう。
型ヒントのための初期設定
静的型チェック
まずは、型ヒントにしたがってコードを書いているかを確認するためのツールを導入します。
pip install mypy
VSCodeへ型チェックツールを導入
VSCodeを使って、Pythonを書きたい方は以下の記事を元に初期設定を行ってください。
※ 日本語化などの設定については、こちらを参考に実施してください。
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) を開く
を選んでください。初期状態だと以下のようなファイルが開くと思います。
{
}
以下のように修正してください。
{
"python.linting.mypyEnabled": true,
}
これで、VSCode
への mypy
の導入が完了しました。
先程の拡張機能に付属する Pylance
の型チェック機能を有効化するには、以下のように設定を追加してください。 設定可能な値は、 basic
または strict
または off
の3つです。
{
"python.linting.mypyEnabled": true,
"python.analysis.typeCheckingMode": "basic",
}
VSCodeに拡張機能を入れると受けれるメリット
先程インストールした拡張機能には、mypy
以外にも恩恵を受けられます。
例えば IntelliSense
はもっとも大きな恩恵の1つと思います。
こちらは初期状態のVSCodeですが、first_name
と打って Ctrl + Space
を打つとなにか入力の補助をしようとしてくれていますが、実際には同じファイル内の文字を羅列しているだけで何の役にも立ちません。
では、拡張機能をインストールした後の状態で確認してみましょう。こちらも first_name.
と打った後は、役に立たなさそうですが、その前の first
と打った時点では、多くのヒント与えてくれています。
これ以外にも、ファイル保存時に自動で black
や autopep8
などが走り、コードを整形(見やすく)してくれる機能があります。初期状態では基本 OFF になっています。こちらの記事などを参考にしてください。
VSCodeにmypyが入っていると?
VSCodeに mypy
のサポート機能が入っていると以下のように入力ミスがあった時に教えてくれます。
これは極端な例ですが、例えば関数の呼び出し時の引数の型が間違っている場合なども教えてくれます。
有効になっていない状態で、試してみると何もエラーが発生しないので、将来的に意図しないエラーが発生するかもしれません。
型チェックの実行
mypy
で型チェックする準備が整ったら以下のようにコマンドを実行します。
以下は、app
ディレクトリ以下のファイル型チェックを行います。
$ mypy sample.py
Success: no issues found in 1 source file
型チェックの無効化
どうしても依存するパッケージ等の問題などで、型ヒントをクリアできない場合は、以下のようにコメントすることで、無効化できます。
明示的にエラーとなっている理由やエラーコードを記載して置くことで次回の更新時の助けになります。
このコメントは1行のみエラーを無視します。
問題のあるコード # type: ignore
VSCodeご利用の方で、Pylance
の型チェック機能を有効にしている場合は、以下のようにして型チェックを回避することができます。このコメントはファイル内すべてで同じエラー名称を無視します。書き方としては # pyright: エラー名称=false
以下が、Pylance
のエラー画面ですが、ピンクの枠で囲んでいる箇所(青いリンク文字)が エラー名称
になります。このエラー名称をコピーして利用します。
# pyright: reportGeneralTypeIssues=false
型ヒントの使い方
型を追加する
それでは、実際に型ヒントの書き方を見ていきましょう。はじめに書いたバージョンから1行だけ修正してみます。
-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_name
が str
型であるとエディターが認識し、 str
型のオブジェクトのメソッドを表示してくれました。
型ヒントの書き方
変数
変数では以下のように型ヒントを書きます。
変数名: 型名
変数名: 型名 = 値
型ヒントのみを書くことができますが、初期化しない状態で利用しようとすると
NameError
が発生します。
標準的なPythonの型
item_1: str
item_2: int
item_3: float
item_4: bool
item_5: bytes
list
python3.6以上の場合は以下のよう書きます。
大文字で始まるListを利用します。
from typing import List
item: List[str]
python3.9以上の場合は以下のように書きます。
builtins.list
が使えるようになりした。
item: list[str]
上記の2つは書き方は違いますが、意味はどちらも str
型の要素を持つ リストであることを明示しています。
tuple と set
python3.6以上の場合は以下のよう書きます。
大文字で始まるTupleを利用します。
from typing import Tuple
item_t: Tuple[str, int, str]
item_s: Set[int]
python3.9 以上の場合は以下のように書きます。
builtins.tuple
と builtins.set
が使えるようになりした。
item_m: tuple[str, int, str]
item_s: set[int]
- 変数 items_t は int, int, str の 3 つの項目からなる タプル であることを明示しています
- 変数 items_s は 各項目は int 型の セット であることを明示しています
dict
python3.6以上の場合は以下のよう書きます。
大文字で始まるDictを利用します。
from typing import Dict
item: Dict[str, int]
python3.9 以上の場合は以下のように書きます。
builtins.dict
が使えるようになりした。
item: dict[str, int]
上記の2つは書き方は違いますが、意味はどちらも str
型のキーと int
型のアイテムを持つ 辞書であることを明示しています。
関数/メソッド
関数では以下のように型ヒントを書きます。
def sample(引数名: 型名, 引数名: 型名, 引数名: 型名, ...) -> 戻り値の型:
return 戻り値
戻り値の方は明示的に記載しないでも、エディターがサポートしてくれる場合もありますが、明示的に書いてあげることでコードの入力を助けてくれます。
引数に int
型とfloat
型の値を取り、戻り値にfloat
型の値を返す関数
def sample1(item_1: int, item_2: float) -> float:
return item_1 * item_2
戻り値がない場合
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)
ユーザー定義クラス
クラスでは以下のように型ヒントを書きます。
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
型を表すようなものは以下のように書きます。
from typing import Union
def process_item(item: Union[int, str]):
print(item)
def process_item(item: int | str):
print(item)
Optional
Optionalは str
のような型を持つ、または None
であることを表現するためのものです。実質的は Union[str, None]
と同義です。
from typing import Optional
item: Optional[str]
item: str | None
記事を更新しました。
- 20220328: 結構読まれているみたいなので、「VSCodeへ型チェックツールを導入」と「lambda」を追加しました。合わせて誤字脱字の修正をしました。
Discussion