
Python 預聲明常量情況怪異2026 年 8 月 1 日消息Python 有 6 個預聲明的“常量”True、False、None、__debug__、Ellipsis也可寫作 ...和 NotImplemented。不過它們的表現因某些原因而略有不同。“True”、“False” 和 “None”特殊關鍵字True、False 和 None 是關鍵字并非標識符而是獨立的詞法標記。這在 Python 里很奇怪因為通常變量是在常規名稱解析過程中確定而非在詞法分析器中。這樣產生了有趣的副作用像 x.True 這樣的表達式會引發 SyntaxError。那么做出這個決定的理由是什么如果有的話呢關于這些常量還有更多有趣之處不過這與其他常量有關聯稍后再講。“__debug__”特殊布爾常量__debug__ 是布爾常量通常為 True但使用 -O 選項運行時為 False這和在非調試版本中禁用 assert 的思路類似。若在“優化”版本中檢查成本過高可用 if __debug__ 包裹代碼。不過__debug__ 很特別。它雖是普通標識符和 True、False 及 None 不同卻是 Python 語言中唯一不能賦值的標識符。代碼示例如下 __debug__ 67File , line 1SyntaxError: cannot assign to __debug__甚至不能將其作為屬性賦值 x.__debug__ 67File , line 1SyntaxError: cannot assign to __debug__同樣沒有其他標識符會這樣這是特殊情況。但由于它不是關鍵字表現與 True、False 和 None 略有不同x.__debug__ 會引發 AttributeError而非 SyntaxError因為它語法上有效只是在查找不存在的屬性。有趣的是嘗試刪除 __debug__ 時有特殊錯誤信息盡管非特殊情況也會引發 NameError但不適用于刪除名為 __debug__ 的屬性 del __debug__File , line 1SyntaxError: cannot delete __debug__ del x.__debug__Traceback (most recent call last):File , line 1, inNameError: name x is not defined若 x 已定義會引發 AttributeError。出于某些原因這兩種情況都不會引發 SyntaxError和賦值情況不同。題外話“SyntaxError” 是假象說到錯誤給 __debug__ 賦值是少數幾種情況之一代碼實際并非語法錯誤卻會引發 SyntaxError。可自行驗證 assert (__debug__ : 67)在調試版本中運行此斷言會引發 SyntaxError但用 -O 選項時斷言不會編譯也就不會引發異常。另外兩個類似情況是在函數外部使用 yield 或 await assert (yield) assert (await 67)“Ellipsis” 和 “NotImplemented”非真正常量Ellipsis 和 NotImplemented 在參考文檔的“常量”部分有記載但和其他 4 個常量不同它們不是“真正的”常量只是普通內置對象因此可被全局變量覆蓋 NotImplemented 67 NotImplemented67同樣不禁好奇這樣設計的理由是什么為何它們不特殊而其他常量卻特殊呢覆蓋常量情況各不同有趣的是盡管 True、False 和 None 是詞法標記但它們也作為普通內置對象存在 import builtins getattr(builtins, True)True getattr(builtins, False)False getattr(builtins, None) is NoneTrue若不使用 getattr就無法直接訪問這些內置對象。但更有趣的是setattr 也能起作用 setattr(builtins, True, 67) getattr(builtins, True)67然而當使用詞法標記訪問時其值并不會改變 TrueTrue__debug__ 也有相同表現 setattr(builtins, __debug__, 67) builtins.__debug__67 __debug__True所以__debug__ 某種程度上可以被賦值但盡管它不是詞法標記卻和 True、False 和 None 一樣是特殊情況對內置模塊的更改不會影響它的值因此它確實是一個常量Ellipsis 和 NotImplemented 再次證明它們實際上不是常量 setattr(builtins, Ellipsis, 67) Ellipsis67不過這不會改變 ... 的值 ...Ellipsis所以從某種意義上說... 是真正的常量而 Ellipsis 不是是不是很奇怪呢