5,893 views
B!0X

TypedDictでpythonのtype hintでdictのkeyとvalueに厳格に型をつける

python-typed-dict

はじめに

この記事では、Pythonの型ヒントを使用してdict型のkeyとvalueの対応に厳格に型をつける方法を紹介します。

動作環境

  • Pythonの型チェックにはpyrightのstrict modeを使用します。
  • Python 3.8

組み込みDictの問題点

Pythonの組み込みのDict型は、厳格にkeyとvalueの対応付けを考慮した型付けができません。例えば以下のような関数があったとします。

def show_animal(a):
    print(a["name"])
    print(a["age"])

この関数は、nameとageのkeyを持ち、かつnameとしてintを、ageとしてintを持つdictのみを受け取りたいとします。ただし、keyだけの制限ならLiteral型を使用すれば制約をかけられます。

from typing import Dict, Literal, Union

Animal = Dict[Literal["name", "age"], Union[str, int]]

def show_animal(a: Animal):
    print(a["name"])
    print(a["age"])

show_animal({"name": "taro", "age": 5}) # OK
show_animal({"name": "taro", "color": "black"}) # NG

しかし、Literal型だけではkeyとvalueの対応付けまでは制限をかけることができません。具体的には以下のような例が通ってしまいます。

show_animal({"name": 5, "age": "taro"}) # OK

このようなケースを許容したくない場合があります。

クラスを用いた解決

クラスを使用し、特に直積型のコンテナとして優れたdataclassを使用すれば、keyとvalueの型の対応付けが保証できます。

from dataclasses import dataclass

@dataclass
class Animal:
    name: str
    age: int

def show_animal(a: Animal):
    print(a.name)
    print(a.age)

show_animal(Animal("taro", 5)) # OK
show_animal(Animal(5, "taro")) # NG

しかし、クラスの定義はいいとして関数に渡すときには該当のインスタンスを生成する必要があります。dictのまま扱いたいときにはこの方法はそぐわないかもしれません。

TypedDictを用いた解決

TypedDictはdictのまま厳格に型を付けることができる便利なクラスです。

from typing import TypedDict

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

def show_animal(a: Animal):
    print(a["name"])
    print(a["age"])

show_animal({"name": "taro", "age": 5}) # OK
show_animal({"name": "taro", "color": "black"}) # NG
show_animal({"name": 5, "age": "taro"}) # NG

これで望み通りにkeyとvalueの対応に対して型が付けられます。TypedDictを用いた定義は継承以外にもいくつか方法が用意されているため、好みの方法で利用できます。

# 他の方法
Animal = TypedDict("Animal", name=str, age=int)
Animal = TypedDict("Animal", {"name": str, "age": int})

おわりに

Pythonの型ヒントと型チェックツールを用いた静的型検査は、しっかりと使うことで効果的にコードの品質を向上させることができます。型ヒントの恩恵を受けることで、より堅牢なプログラムを構築してください。

関連事例

  • データ分析支援

    事例:過去実績を提案に活用する分析の仕組み

    広告代理店との取り組みです。同社は過去実績の示唆を次の提案へ反映し、結果をどのように予測したか、その背景まで提案先のクライアントへ説明できるようになりました。KDOT は案ごとの見込みと判断材料を比較できる仕組みを業務アプリとして実装しました。さらに業務アプリの中核となる処理ロジックと機械学習モデルについて、特許手続きを担う弁理士が技術の新規性や工夫を検討するための資料を作成しました。その後この発明には特許が付与されました。

  • データ基盤構築 / 技術顧問(技術企業向け)

    事例:効果検証の分析処理基盤

    効果検証を提供する分析会社との取り組みです。同社は分析者の人数に比例してしか売上と利益を伸ばせない事業の形を、効果検証をプロダクトとして提供することで変革しようとしていました。手法とモデルは同社のまま、社内では開発できなかった、データと機械学習の重い推定を製品として動かす仕組みの開発を、開発支援会社の KDOT に任せました。推定を案件ごとの手作業ではなくシステムで実行できるようになったことで、同社は人数に比例しない形で売上と利益を伸ばすことを目指せるようになりました。

開発の相談先をお探しですか。

この記事に関わることについてご相談がある方はお問い合わせください。

KDOT についてお問い合わせ