🦁
Pythonで一部のキーが存在しない型を定義する
Python 3.8以降では、TypedDictを使用して辞書のキーとその値の型を定義することができます。
時には、キーが必須ではなく、オプショナルである(キーが存在しない)型を定義したい場合があります。
TypeScriptにおける次のような型をPythonで定義する方法を考えます。
type User = {
name: string;
email?: string;
}
Optionalでの実装例と問題点
Optionalを使用すると、キーは常に存在するが、値がNoneになる可能性を示します。
そのため、外部リソースからデータを取得する場面でキーが存在しない可能性があるにも関わらず、誤ってOptionalを利用すると意図せぬバグを生む可能性があります。
from typing import TypedDict, Optional
class User(TypedDict):
name: str
email: Optional[str]
def hello(user: User):
print(f"Hello, {user['name']}")
# 本来はemailが存在しない可能性があるが、誤ってOptinalで型指定しているため、型チェックでエラーとならず実行時にエラーが発生する
print(f"Your email is {user['email']}")
NotRequiredによる解決策
Python3.11以降であれば、NotRequiredを使用して特定のキーが存在しないことを示す型を定義できます。
これにより、キーの存在チェックをせずに参照している場合に型エラーが発生します。
from typing import TypedDict, NotRequired
class User(TypedDict):
name: str
email: NotRequired[str]
def hello(user: User):
print(f"Hello, {user['name']}")
# Could not access item in TypedDict "email" is not a required key in "User", so access may result in runtime exception
print(f"Your email is {user['name']}")
まとめ
キーが任意で存在しない可能性がある型を定義したい場合は、NotRequiredを使用しましょう。
Discussion