Traffine I/O

日本語

2022-04-01

PythonのLiteral型

PythonのLiteral型

Python 3.8で導入されたtyping.Literalは、特定の値に制約された型を指定するために使用されます。例えば、Literal[1, 2, 3]は、12、または3のいずれかの型を示します。これは他の型ヒントと組み合わせて、より正確な型注釈を作成するために使用することができます。

typing.Literalは実行時にこれらの制約をチェックしませんが、タイプチェッカーやリンター、IDEの機能によってチェックされます。これにより、コードを実行する前にバグを見つけるのに役立ち、コードを自己文書化することができます。

typing.Literalの構文

基本的な構文はLiteral[val1, val2, ...]であり、val1, val2, ...は具体的な値です。以下に基本的な使用例を示します。

python
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型を使用することで、これを明示することができます。

python
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.LiteralEnumは、いずれも値を限定されたオプションに制約するという目的な目的で使用されますが、いくつかの違いがあります。

  • 型情報
    typing.Literalでは、変数が取りうる具体的な値を指定します。enum.Enumでは、異なる値を持つ独立した値を作成し、変数の型はenum自体であり、enumアイテムの値ではありません。

  • 実行時のチェック
    Pythonのenumは実行時にチェックされます。無効な値をenumに割り当てようとすると、実行時エラーが発生します。一方、typing.Literalは実行時の保証を提供しません。その制約は、タイプチェッカーやリンター、IDEの機能によってのみチェックされます。

  • コードの明瞭さ
    Enumはコードを自己文書化するのに役立ちます。typing.Literalでは、取りうる具体的な値を確認することができますが、意味的なラベルは得られません。

参考

https://peps.python.org/pep-0586/

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!