Pythonにおいて、'None'は値が欠落していること、エラーが発生したこと、または設定が未設定であることを示す「スイスアーミーナイフ」として頻繁に使用されます。しかし、この多機能性は意味論的な曖昧さを生み出します。例えば、キャッシュシステムにおいて、戻り値の'None'は、辞書にキーが存在しないことを意味するのか、あるいはキーは存在するが明示的に'None'にマッピングされていることを意味するのかを判別できません。同様に、設定の更新において、'timeout=None'というパラメータは、実装によっては「タイムアウトなし」とも「既存の値を維持する」とも解釈される可能性があります。これらの衝突を解決するために、開発者はセンチネル値を使用できます。これは有効なデータのドメイン外に存在するユニークなオブジェクトであり、実際の値と決して重複しないことを保証します。
Pythonの標準ライブラリは、複雑な動作を管理するためにすでにいくつかの組み込みセンチネルを利用しています。'Ellipsis' (...) オブジェクトはNumPyのスライシングで次元をスキップするために使用され、'NotImplemented'は他の場所で実装を見つけるための信号として機能し、バイナリ演算子の「ダブルディスパッチ」を可能にします。より最近では、Pydanticライブラリが、送信されなかったフィールドと明示的にnullに設定されたフィールドを区別するために'MISSING'センチネルを導入しました。歴史的に、開発者は'object()'を使用してカスタムセンチネルを作成してきましたが、このアプローチはMyPyのようなツールにおける静的な型絞り込みを損なうことがよくありました。'Literal'文字列や'Enum'のトリックといった回避策も一般的でしたが、それらはアイデンティティチェックやピクリングに関してトレードオフを伴うことが多々ありました。
PEP 661の承認に伴い、Python 3.15ではこのパターンを標準化するための専用の組み込み'sentinel'が導入されました。これにより、型チェッカーは'None'と同様に型を絞り込むことができるようになります。例えば、関数はパラメータが正確に'sentinel'値であるかどうかをチェックしてアクションをスキップすべきかを判断でき、同時に'None'を有効な「空」の状態として表現し続けることができます。新しい組み込みセンチネルはAPI設計のためのよりクリーンなパスを提供しますが、古いバージョンの開発者はバックポートのために'typing_extensions'を使用できます。正式なセンチネルへの移行は、Pythonにおけるより正確な意味論への動きを強調しており、過負荷な'None'の使用から、不在を明示的かつ型安全に表現する方向へと移行しています。
