Python型ヒント:より安全で明確なコードを書く

Backend2026-09-13TryQuickToolBox

入力に応じて異なる型を返すPython関数や、途中で型が変わる変数に遭遇したことがあるでしょう。これらの曖昧さは、もっと早くに発見できたはずの実行時エラーにつながります。Pythonの型ヒントは、期待される型を注釈として記述できるようにすることでこれを解決し、コードを自己文書化するとともに、静的解析ツールが実行前に間違いを発見できるようにします。

この記事では、基本的なアノテーションから高度なパターンまで、Pythonで型ヒントを効果的に使う方法と、それらがどのように安全で明確なコードに貢献するかを探ります。

Pythonの型ヒントとは?

型ヒント(型アノテーションとも呼ばれる)は、Python 3.5(PEP 484)で導入された構文で、変数、関数の引数、戻り値の期待される型を指定できます。実行時には強制されませんが、mypy、pyright、IDEなどの静的型チェッカーによって型関連のエラーを検出するために使用されます。

例えば:

def greet(name: str) -> str:
    return f"Hello, {name}"

ここで、name: strはnameが文字列であるべきことを示し、-> strは関数が文字列を返すことを示します。

なぜ型ヒントを使うのか?

基本的な型アノテーション

変数、関数の引数、戻り値の型をアノテートできます。

変数

age: int = 30
name: str = "Alice"

関数

def add(a: int, b: int) -> int:
    return a + b

コレクション

リスト、辞書などには、typingモジュール(またはPython 3.9+の組み込みジェネリクス)を使用します:

from typing import List, Dict

def process(items: List[str]) -> Dict[str, int]:
    return {item: len(item) for item in items}

Python 3.9+では、list[str]やdict[str, int]を直接使用できます。

高度な型ヒント

コードが成長するにつれて、より複雑なシナリオに遭遇します。ここではいくつかの高度な機能を紹介します。

OptionalとUnion

Optional[T]はUnion[T, None]の省略形で、型TまたはNoneの値を示します。

from typing import Optional

def find_user(user_id: int) -> Optional[str]:
    # returns username or None if not found
    ...

Python 3.10+では、|演算子を使用できます:str | None。

Callable

引数としての関数:

from typing import Callable

def apply_func(func: Callable[[int], int], value: int) -> int:
    return func(value)

ジェネリクス

型変数を使って再利用可能なコンポーネントを作成:

from typing import TypeVar, List

T = TypeVar('T')

def first(items: List[T]) -> T:
    return items[0]

TypedDict

固定されたキーと値の型を持つ辞書:

from typing import TypedDict

class User(TypedDict):
    name: str
    age: int

def greet(user: User) -> str:
    return f"Hello, {user['name']}"

静的型チェッカーの使用

型ヒントは、チェックして初めて役立ちます。人気のあるツールにはmypy、pyright、pyreがあります。mypyの使い方を見てみましょう。

  1. mypyをインストール:pip install mypy
  2. コードに対して実行:mypy your_script.py
  3. 報告されたエラーを修正。

例えば、次のコードがあるとします:

def add(a: int, b: int) -> int:
    return a + b

add("1", "2")

mypyは次のように報告します:error: Argument 1 to "add" has incompatible type "str"; expected "int"。

mypy.iniまたはpyproject.tomlファイルでmypyを設定し、より厳密なチェックを強制できます。

型ヒントのベストプラクティス

よくある落とし穴と回避方法

実践での型ヒント:小さな例

数値のリストを処理して平均を返す関数を考えてみましょう。型ヒントがないと、どのような型が期待されるか不明確です。

def average(numbers):
    return sum(numbers) / len(numbers)

型ヒントを使うと:

from typing import List

def average(numbers: List[float]) -> float:
    return sum(numbers) / len(numbers)

これで、誰かが文字列のリストを渡すと、mypyが指摘します。

型ヒントをワークフローに統合する

型ヒントを最大限に活用するには、開発プロセスに統合しましょう:

  1. 既存のコードベースに徐々に型ヒントを追加する。
  2. IDEが型エラーを表示するように設定する。
  3. CIパイプラインに型チェックステップを追加する。
  4. コミット前にmypyを実行するpre-commitフックを使用する。

例えば、シンプルなGitHub Actionsワークフローステップ:

- name: Type check
  run: mypy .

FAQ

型ヒントは実行時のパフォーマンスに影響しますか?

いいえ、型ヒントは実行時には無視されます。それらは__annotations__に保存されますが、実行速度には影響しません。

古いPythonバージョンで型ヒントを使用できますか?

型ヒントはPython 3.5で導入されました。古いバージョンでは、コメントベースのアノテーション(例:# type: int)を使用できますが、サポートされているPythonバージョンにアップグレードすることをお勧めします。

型ヒントにおけるListとlistの違いは何ですか?

typingのListはPython 3.5-3.8で使用されます。Python 3.9+では、組み込みのlistを直接使用できます。型チェックにはどちらも同等です。

コード品質を向上させる準備はできましたか?今日から1つの関数に型ヒントを追加し、mypyを実行してその利点を確認しましょう。その他の開発者ツールについては、JSON Formatterをチェックして、JSONデータを簡単に整形および検証してください。