iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
佛心分享-IT 人自學之術

It Works on My Machine:30 天從踩雷學會工程事故調查系列 第 11

Day 11|踩雷:換行多了一個逗號,Python 居然照常執行

  • 分享至 

  • xImage
  •  

本篇是故事三的「踩雷」篇。

本篇要回答:一段語法完全合法的程式,如何在沒有任何錯誤訊息的情況下改變資料型別?

當時發生了什麼

整理一段多行賦值的程式碼時,行尾多留了一個逗號。Python 沒有任何抱怨——沒有 SyntaxError、沒有警告,程式照常執行,測試也沒有當場翻臉。異常在很下游的地方才第一次現形,而且錯誤訊息指向的位置,距離那個逗號非常遠。

(去識別化說明:當時的原始程式碼與確切換行結構已不在手邊,本故事以重建的最小案例呈現機制;範例中的程式行為皆實際執行驗證過。)

最小重建長這樣:

value = 42
result = value,     # 行尾多了一個逗號
print(repr(result)) # (42,)
print(type(result)) # <class 'tuple'>

result 拿到的不是 42,是 (42,)——單元素 tuple。決定 tuple 的從來不是括號,是逗號。

我原本怎麼判斷

當時的直覺鏈是:語法合法 → 程式正確;能執行 → 資料沒問題;測試通過 → 可以收工。三段推論每一段都在偷換概念。Python 從頭到尾只承諾了一件事:這段語法合法。它沒有承諾這段程式表達了我的意圖。

另一個落空的期待是工具:formatter 不會刪掉這個逗號——對它來說,value, 是有語意的合法表達式,格式化工具的職責是排版,不是猜測我要的型別。

我怎麼查證或重現

三個問題釘住現場。第一,為什麼沒有 SyntaxError?因為 value, 就是合法的 tuple 建構語法,語言規格如此,不是漏洞。第二,當時預期的型別是什麼?單一值。第三,程式在哪一層第一次表現異常?不在賦值處,而在某個終於「在乎精確結構」的下游邊界——中間隔著的每一層都對 tuple 照單全收(Day 13 會完整重建這條路徑)。

區分證據等級。已確認事實:上述最小案例的行為(已執行驗證,任何 Python 3 可重現)。合理推論:當時的事故機制與最小案例一致。已不可考:原始程式碼的確切結構——所以本系列用最小重現代替回憶,不憑印象重寫「當時的程式」。

今天留下什麼方法

留下一句需要反覆咀嚼的區分,也是本篇結論:

Python 沒有說這段程式正確;它只表示這段語法合法。

下一篇(Day 12)建立資料採證的基本功:不要只印出值,還要確認它到底是什麼。


上一篇
Day 10|內化:不要只叫大家記得 activate,讓專案自己說明怎麼跑
下一篇
Day 12|查證:不要只印出值,還要確認它到底是什麼
系列文
It Works on My Machine:30 天從踩雷學會工程事故調查12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言