Pythonの事前宣言定数の挙動が不統一
Pythonの6つの事前宣言定数(True、False、None、__debug__、Ellipsis、NotImplemented)は実装方式が異なり、代入可否や組み込みモジュールとの関係に一貫性がない。
Pythonは6つの事前宣言定数を持つが、それぞれの挙動は大きく異なる。True、False、Noneは字句トークンとして実装されたキーワードであり、一般的な識別子ではない。一方、__debug__はブール定数で、通常はTrueだが -O オプションで実行するとFalseになる。EllipsisとNotImplementedはリファレンスの「定数」セクションに記載されているが、他の4つと異なり真の定数ではなく、単なる組み込みオブジェクトである。
字句トークンとしての定数
True、False、Noneは字句トークンとして実装されており、属性アクセスで参照しようとするとSyntaxErrorが発生する。例えば「x.True」とすればSyntaxErrorが raise される。また getattr(builtins, 'True') で組み込みモジュール経由でアクセスすることは可能だが、setattr(builtins, 'True', 67) で組み込みを変更しても、字句トークン True の値は変わらない。
__debug__の特殊な扱い
__debug__はブール定数で、通常はTrue、-O オプションで実行するとFalseになる。直接代入しようとすると「__debug__ = 67」のように記述した場合「SyntaxError: cannot assign to __debug__」が発生する。属性経由での代入「x.__debug__ = 67」も同じくSyntaxErrorが raise される。del __debug__でも削除不可であり、SyntaxErrorが発生する。一方、setattr(builtins, '__debug__', 67) で組み込みを変更しても、__debug__は依然としてTrueを返す。
EllipsisとNotImplementedの柔軟性
EllipsisとNotImplementedは通常の組み込みオブジェクトであるため、シャドーイング(上書き)が可能だ。NotImplemented = 67 で直接上書きできる。ただし ... 構文は setattr(builtins, 'Ellipsis', 67) で組み込みを変更した後でも依然としてEllipsisを返す。これはEllipsisが特別な字句トークン構文を持つためである。
筆者の見立て
- True、False、Noneをレジュラーな名前解決ではなく字句トークンとして実装した理由が不明であると論じている。
- これらの定数の一貫性のない扱いは、統一された設計原則の欠如を示唆している。
- EllipsisとNotImplementedが他の定数と異なる扱いを受ける理由が明確でないと考えている。
この記事は元記事の事実のみに基づいて自動生成されました。
出典
sebsite.pw、"python's pre-declared constants are kinda weird"、https://sebsite.pw/w/20260801-pythonconstants.html