問題の歴史
関数のアノテーションはPython 3.0で導入され、type hints(型ヒント)のメカニズムはPEP 484で説明され、3.5で追加されました。このツールは静的コード分析、自動補完、可読性の向上のために作成されており、型ライブラリ(typing)を使用して変数、引数及び関数の戻り値の期待される型を明示的に指定することができます。
問題
Pythonは動的な言語であり、変数の型は実行中に変化する可能性があり、プログラム実行時にのみエラーが発生する可能性があることがあります。アノテーションはコードの実行に影響を与えませんが、誤用されることで開発者は「厳密な型付け」の誤った感覚を抱くことになります。
解決策
型のアノテーションは、ドキュメント作成、mypy、pylance、pyrightなどのツールによる自動検証、IDEとの統合のために使用されます。これは引数名の後にコロンを置き、パラメータリストの後に矢印を付けて実装されます:**
def greet(name: str, times: int = 1) -> None: for _ in range(times): print(f"Hello, {name}!") # 辞書を処理する関数の正しいアノテーション from typing import Dict, List def transform(data: Dict[str, List[int]]) -> float: return sum(sum(lst) for lst in data.values()) / 10
主な特徴:
Pythonはアノテーションで宣言された型の適合性を「自動的」に検証できますか?
いいえ!型検証はmypyなどの静的分析ツールによってのみ行われ、runtime中にPythonはアノテーションの内容を完全に無視します。
def f(x: int): return x * 2 print(f('oops')) # 型はstrですが、エラーは発生しません!
アノテーションはどこに保存され、runtime中にどのように取得され、なぜそれが必要ですか?
特別な属性__annotations__に保存されています:
def add(x: int, y: int) -> int: return x + y print(add.__annotations__) # {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}
これはデータの検証、自動化されたドキュメント生成、シリアライゼーションなどのためにサードパーティのライブラリによって使用されます。
任意の変数をアノテーションすることはできますか、それとも関数のみ、グローバル空間ではどうなりますか?
ローカルおよびグローバル変数の両方をコロンでアノテーションできますが、これも実行には影響しません:
index: int = 0 def func(x: 'User') -> None: ...
企業プロジェクトで、すべての開発者がアノテーションを積極的に導入したが、関数の実際の引数の型が指定されたものと一致しないことがしばしばあった。Pythonはこれらのエラーを無視し、予期しないバグがビジネスロジックの深い部分でのみ現れた。mypyの設定がなかった。
長所:
短所:
type hintsの使用とCIでのmypyの必須実行、そして__annotations__によるドキュメントの自動生成:
長所:
短所: