MENU

Pythonの型ヒント入門|書き方と業務スクリプトでの使い方

当ページのリンクには広告(PR)が含まれていることがあります。
【最新】Pythonの型ヒント入門|使い方・メリットを解説のアイキャッチ
お悩み女子

コードの中に name: str とか -> int とか書いてあるけど、これは何のために付いているの?

型ヒントは変数や関数の引数・戻り値に「ここにはこの種類の値が入る予定です」と書き添える仕組みです。数か月後に自分や同僚がスクリプトを読み返したとき、何を渡して何が返ってくるのかがひと目で分かります。

型ヒントの書き方と、業務スクリプトで間違いを見つけるチェック方法を、動くコードつきで紹介します。載せているコードはWindows 11 と Python 3.12 で動くことを確かめています。チェックには mypy(型ヒントの書き間違いを実行前に見つけるツール)を使い、確かめたバージョンは 2.4.0 です。

この記事でわかること
  • 型ヒントの書き方(引数・戻り値・変数)
  • 業務スクリプトでよく使う型と、None が返る関数の書き方
  • 型ヒントは実行時に守られない、という事実
  • mypy で書き間違いを実行前に見つける手順
  • 売上CSVの集計コードに型ヒントを付ける例
目次

Pythonの型ヒントの仕組み

型ヒント(タイプヒント)を支える typing モジュールは、Python 3.5 で加わりました。公式の用語集では変数・クラス属性・関数の引数や戻り値について、期待される型を指定する注釈と説明されています。まずは書き方を見てみます。

def format_amount(amount: int) -> str:
    return f"{amount:,}円"


store_name: str = "東京店"
print(store_name, format_amount(1234567))

実行結果は次のとおりです。

東京店 1,234,567円

引数の名前の後ろに「: int」と書くと、amount には整数が入る予定、という意味になります。関数の定義の最後に「-> str」と書くと、文字列を返す予定、という意味です。変数も同じ形で、store_name: str = "東京店" のように名前の後ろに型を書きます。

型ヒントは Python の標準の書き方で、追加のインストールは要りません。書いておくと、次の3つで役に立ちます。

  • 読む人への説明になる。関数の中身を読まなくても、渡すものと返るものが分かる
  • チェックツールが間違いを見つけられる。実行する前に、型の食い違いを指摘してくれる
  • エディタの補完が効きやすくなる。公式の用語集にもIDE のコード補完を助ける、と書かれている

型ヒントの書き方|業務スクリプトでよく使う型8つ

業務の自動化で出番が多いのは、文字・数・True/False・リスト・辞書・ファイルの場所・値なしを表す型です。先に一覧を見て、あとで1つずつ書き方を確かめます。

スクロールできます
書き方意味業務での例
str文字列店舗名、ファイル名
int整数金額、件数
float小数平均、割合
boolTrue か False処理済みかどうか
list[str]文字列が並んだリスト店舗名の一覧
dict[str, int]キーが文字列、値が整数の辞書店舗ごとの売上
Pathファイルやフォルダの場所(pathlib)読み込むCSVの場所
int | None整数、または None(値なし)見つからなければ None を返す関数

文字・数・True/Falseの型

str・int・float・bool は、そのまま型の名前として書けます。変数に付けるときは、名前の後ろに「: 型」を置きます。

store: str = "東京店"
count: int = 3
names: list[str] = ["東京", "大阪", "名古屋"]
sales: dict[str, int] = {"東京": 120000, "大阪": 98000}
memo: str | None = None

リストと辞書の中身の型

リストと辞書は、角括弧の中に中身の型を書きます。list[str] は文字列のリスト、dict[str, int] はキーが文字列で値が整数の辞書です。

この書き方は Python 3.9 以降で使えます。int | None のように縦線で型をつなぐ書き方は、公式ドキュメントでは Python 3.10 以降とされています。古い Python での書き方は後ほど紹介します。

値がないときのNone

探した値が見つからないときに None(値なし)を返す関数は、業務の自動化でよく書きます。戻り値は int | None のように、整数または None と書きます。

def find_price(prices: dict[str, int], name: str) -> int | None:
    return prices.get(name)


print(find_price({"りんご": 120}, "りんご"))
print(find_price({"りんご": 120}, "みかん"))

実行すると、次のように表示されます。

120
None

2行目の None は、辞書に「みかん」がなかったという意味です。戻り値が None になる可能性を型で示しておくと、後のチェックで役に立ちます。

Python実行時の型ヒントの扱い

型ヒントで最初に知っておきたいのは、Python は型ヒントを守らせないという点です。公式ドキュメントには「Python ランタイムは、関数や変数の型アノテーションを強制しません」と書かれています。実際に確かめます。

def double(amount: int) -> int:
    return amount * 2


print(double(1500))
print(double("1500"))

出力は次のとおりです。

3000
15001500

2回目は "1500" と引用符で囲んだ文字列を渡していますが、エラーは出ません。文字列に2をかけると同じ文字列を2回つなげる動きになり、15001500 が返ります。

CSV から読み込んだ金額は、そのままだと文字列です。金額を数に直し忘れても、エラーにならないまま計算が進むことがあります。

合計や平均の数字が合わなくなるまで、間違いに気づけません。エラーで止まる間違いより、気づかないうちに処理が進む間違いのほうが見つけにくくなります。

お悩み女子

じゃあ、書いても意味がないんじゃない?

なべくん

守らせるのではなく、読んで間違いを探してくれるツールに任せます。次の章の mypy がそれです。

型ヒントのチェック|mypyで実行前に間違いを見つける

mypy はコードを動かさずに、型ヒントと実際の使い方を突き合わせるツールです。

mypyの用意と実行の手順

作業用のフォルダに仮想環境(そのフォルダだけで使うライブラリの置き場)を作り、そこに mypy を入れます。コマンドプロンプトで、次の3行を順に実行します。

py -3.12 -m venv venv
venv\Scripts\python.exe -m pip install mypy
venv\Scripts\python.exe -m mypy check.py

2行目で mypy を入れ、3行目で check.py(さきほどの double 関数のファイル)を調べます。

会社のPCではpip でライブラリを入れてよいかを先に確認してください。仮想環境を使えば Python 本体には手を加えませんが、入れる行為そのものが禁止されている職場もあります。

型の間違いを指摘された例

mypy の出力は次のとおりです。

check.py:6: error: Argument 1 to "double" has incompatible type "str"; expected "int"  [arg-type]
Found 1 error in 1 file (checked 1 source file)

読み方は単純です。6行目で、double の1つ目の引数が str(文字列)になっている。期待されているのは int(整数)、という指摘です。

None の扱いも見つけてくれます。find_price 関数の下に、結果へそのまま10を足す2行を書き足して price_check.py として調べます。

price = find_price({"りんご": 120}, "みかん")
print(price + 10)
price_check.py:6: error: Unsupported operand types for + ("None" and "int")  [operator]
price_check.py:6: note: Left operand is of type "int | None"
Found 1 error in 1 file (checked 1 source file)

None に足し算はできないという指摘です。動かすと TypeError で止まります。if price is not None: で None かどうかを先に調べる形に直すと、指摘は消えます。

注意点もあります。公式ドキュメントによると、mypy は型ヒントのない関数を既定ではチェックしません。上の double から型ヒントを外すと mypy は「Success: no issues found」と表示しますが、動かすと TypeError で止まります。チェックしてほしい関数には型ヒントを付けておきます。

型ヒントを業務スクリプトで使う|売上CSVの集計を例に

ここまでの内容を、売上CSVを読んで合計と平均を出すスクリプトで組み合わせます。数か月後に読み返す、同僚に渡すといった場面を想定した書き方です。

売上CSVを集計するコード

読み込むのは、次の3店舗分の売上です。ファイル名は sales.csv とします。

店舗,金額
東京,120000
大阪,98000
名古屋,75000
import csv
from pathlib import Path


def read_sales(path: Path) -> list[dict[str, str]]:
    with path.open(encoding="utf-8-sig", newline="") as f:
        return list(csv.DictReader(f))


def total_amount(rows: list[dict[str, str]]) -> int:
    return sum(int(row["金額"]) for row in rows)


def average_amount(rows: list[dict[str, str]]) -> float:
    return total_amount(rows) / len(rows)


rows = read_sales(Path("sales.csv"))
print(f"合計: {total_amount(rows):,}円")
print(f"平均: {average_amount(rows):,.0f}円")

sales_total.py として実行すると、合計と平均が表示されます。

合計: 293,000円
平均: 97,667円

関数ごとに、何を受け取って何を返すかが見えるのがポイントです。read_sales は Path を受け取って文字列の辞書のリストを返し、total_amount はそのリストから整数を、average_amount は小数を返します。CSV の金額は文字列なので、合計の関数の中で int() で数に直しています。

このコードに mypy をかけると、「Success: no issues found in 1 source file」と表示されます。

mypyが見つける2つの書き間違い

わざと2か所を書き換えます。14行目で平均の戻り値を int と書き、18行目で Path ではなく文字列を渡します。

# 14行目: 平均は小数になるのに、戻り値を int と書いた
def average_amount(rows: list[dict[str, str]]) -> int:

# 18行目: Path ではなく文字列を渡した
rows = read_sales("sales.csv")
sales_total.py:15: error: Incompatible return value type (got "float", expected "int")  [return-value]
sales_total.py:18: error: Argument 1 to "read_sales" has incompatible type "str"; expected "Path"  [arg-type]
Found 2 errors in 1 file (checked 1 source file)

2つとも、動かす前に指摘されます。14行目の間違いは return の行(15行目)で指摘されています。18行目の間違いは実行すると AttributeError: 'str' object has no attribute 'open' で止まります。一方、14行目だけの間違いは実行してもエラーにならず、画面には平均が表示されます。型ヒントだけが食い違っている状態です。

後からコードを直すときの型チェック

スクリプトはCSVの列を増やす、金額を税込にする、関数を別のファイルに移すなど、作った後に手を入れる場面がよくあります。そのたびに mypy をかけると、「戻り値を変えたのに、呼び出す側が古いままだった」といった食い違いを実行前に拾えます。変更の影響が出る場所を機械に探してもらえるのが、自動化コードに型ヒントを付ける一番の理由です。

型ヒントを書く範囲|関数の引数と戻り値から

型ヒントは全部に付けなくても動きます。手間に対して効果が大きい場所から始めるのが、続けやすい進め方です。

最初に付ける場所

筆者なら、まず関数の引数と戻り値に付けます。関数は何を渡して何が返るかの約束事なので、ここが書いてあるだけで、読む人の迷いが減ります。

変数への型ヒントはmemo: str | None = None のように中身がすぐ決まらないときだけで足ります。

生成AIに書かせたコードや、検索で見つけたコードにも、型ヒント付きのものがあります。ヒントがあれば読みやすい反面、書かれた型が実際のデータと合っているかは人が確かめます。たとえば、CSV から読んだ金額に int と書かれていないか、といった点です。

辞書の項目名まで決めたいときの TypedDict など、この記事で扱っていない書き方は、公式ドキュメントの typing モジュールのページで調べられます。

古いコードで見かける書き方

古いコードや解説では、from typing import Dict, Optional のように typing モジュールから型を読み込む書き方が出てきます。Optional[int] は int | None と同じ意味、Dict[str, int] は dict[str, int] と同じ扱いで、Python 3.12 でも動きます。

公式ドキュメントでは、Dict や List は Python 3.9 以降「非推奨のエイリアス」とされていますが、削除の予定は今のところない、とされています(2026年10月時点)。新しく書くなら、短い書き方で足ります。

型ヒントに関するよくある質問

型ヒントについて、よくある疑問をまとめました。

型ヒントを書くと、プログラムは速くなりますか?

速くなる仕組みではありません。Python は実行時に型ヒントを強制せず、チェックツールやエディタが読むための情報として使います。

list[str] と書くとエラーになる場合は?

古い Python を使っている可能性があります。公式ドキュメントでは、list[str] のような書き方は Python 3.9 以降とされています。それより前の場合は、from typing import List を使って List[str] と書きます。

型ヒントとmypyの役割

型ヒントのポイントを整理します。

この記事のまとめ

型ヒントとは:引数・戻り値・変数に、入る値の種類を書き添える仕組み。
よく使う型:str・int・float・bool・list[str]・dict[str, int]・Path・int | None。
実行時の扱い:Python は型ヒントを守らせない。違う型を渡してもエラーにならない。
チェック方法:mypy を使うと、動かす前に型の食い違いを指摘してくれる。ヒントのない関数は見てもらえない。
書く場所:最初は関数の引数と戻り値から。

まずは、手元のスクリプトにある関数を1つ選んで型ヒントを付け、mypy で Success と出るかを確かめてみてください。

型ヒントと一緒に読むと役立つ記事を紹介します。

参考資料
typing — 型ヒントのサポート | Python 3 ドキュメント
用語集: 型ヒント | Python 3 ドキュメント
PEP 484 Type Hints
Getting started | mypy ドキュメント

この記事を書いた人

Watanabeのアバター Watanabe サイト運営者

2020年よりブログ開始。
SEOが思いのほか性にあっていたようで現在に至る。
モットーは「勝率の高い選択をする」
AIは活用するが吉、最後は人間が息を吹き込む。
アートと科学を追求し、日々精進。
―――
収益:6~7桁をウゴウゴ。
サイト:ペラサイト~中規模サイトまで運営中。
案件:1000円以上の案件をメインに取組中。
打ち手:ブラックSEO~ホワイトSEOまで
―――

目次