PythonのLiteral型
Python 3.8で導入されたtyping.Literal
は、特定の値に制約された型を指定するために使用されます。例えば、Literal[1, 2, 3]
は、1
、2
、または3
のいずれかの型を示します。これは他の型ヒントと組み合わせて、より正確な型注釈を作成するために使用することができます。
typing.Literal
は実行時にこれらの制約をチェックしませんが、タイプチェッカーやリンター、IDEの機能によってチェックされます。これにより、コードを実行する前にバグを見つけるのに役立ち、コードを自己文書化することができます。
typing.Literalの構文
基本的な構文はLiteral[val1, val2, ...]
であり、val1, val2, ...
は具体的な値です。以下に基本的な使用例を示します。
from typing import Literal
def get_status(status: Literal["connected", "disconnected", "idle"]) -> None:
pass
この例では、get_status
関数は3つのステータス文字列のいずれかを受け取ることが期待されています。それ以外の値は、タイプチェッカーによって不正とみなされますが、Python自体は実行時にこれを強制しません。
Literal型は、関数が特定の値のセットのみを期待する場合に主に使用されます。例えば、HTTPメソッドを処理する関数は、"GET"、"POST"、"PUT"、"DELETE"などのメソッドのみを受け入れる場合があります。Literal型を使用することで、これを明示することができます。
from typing import Literal, Optional, Dict, Any
def handle_request(method: Literal["GET", "POST", "PUT", "DELETE"], url: str, data: Optional[Dict[str, Any]] = None) -> None:
pass
この例では、handle_request
関数は、文字列としての4つのHTTPメソッドのいずれかを受け取ることが期待されています。他の値はタイプチェッカーによってフラグが立てられます。これにより、コードが自己文書化され、コードを実行する前にバグを見つけるのに役立ちます。
Literal型とEnumの比較
typing.Literal
とEnumは、いずれも値を限定されたオプションに制約するという目的な目的で使用されますが、いくつかの違いがあります。
-
型情報
typing.Literal
では、変数が取りうる具体的な値を指定します。enum.Enum
では、異なる値を持つ独立した値を作成し、変数の型はenum自体であり、enumアイテムの値ではありません。 -
実行時のチェック
Pythonのenumは実行時にチェックされます。無効な値をenumに割り当てようとすると、実行時エラーが発生します。一方、typing.Literal
は実行時の保証を提供しません。その制約は、タイプチェッカーやリンター、IDEの機能によってのみチェックされます。 -
コードの明瞭さ
Enumはコードを自己文書化するのに役立ちます。typing.Literal
では、取りうる具体的な値を確認することができますが、意味的なラベルは得られません。
参考