本篇是故事二的「內化」篇。
本篇要回答:怎麼把「這次修好了」升級成「這類問題不再發生,或發生時十分鐘內可以定位」?
修好之後最省事的防再發措施是一句口號:「大家記得啟用虛擬環境。」它跟「下次注意」屬於同一族——說完的當下人人點頭,三個月後新人報到,同一齣戲重演。Day 09 的促成因素清單已經指出:所有依賴人工記憶的步驟,都是排隊等著發生的事故。
過去我把環境設定當成每個人自己的事:會的人自然會,不會的人問一下就好。這個想法的盲點在於,它把「環境正確」變成一種默契,而默契沒有驗證方式、沒有回退方法、出事時也沒有紀錄可查——用 Day 05 模板的語言說,這是一項沒有驗收方式的隱形需求。
把 Day 09 的促成因素逐條翻面,變成可驗證的措施:
| 促成因素 | 對應措施 | 驗證方式 |
|---|---|---|
| 沒固定 Python 版本 | 版本檔與相依鎖定納入版控 | 新機器照文件能建出相同環境 |
| pip 與 python -m pip 混用 | 文件與腳本一律 python -m pip、python -m pytest | grep 檢查文件與 CI 腳本 |
| 執行方式口耳相傳 | 統一入口:專案腳本、Makefile 或 Task Runner | 新人只靠 README 能跑完測試 |
| 測試輸出無環境資訊 | 測試啟動時印出 sys.executable 與版本 | 每份測試紀錄可回答「跑在哪」 |
| IDE 設定只在個人機器 | README 寫明 interpreter 設定步驟與檢查點 | 換機重設可在十分鐘內完成 |
| 環境正確與否靠默契 | 環境檢查腳本:比對 interpreter、版本、關鍵套件 | 腳本在錯誤環境下以非零 exit code 失敗 |
搭配一條 CI 原則:CI 使用與本機相同的安裝與測試流程——CI 綠燈才能回答「乾淨環境照文件走得通」,而不是「CI 自己另有一套魔法」。
本專案的實作範例是 scripts/install.py:它探索本機的 Python、只提供符合版本下限的選項、建立專案自己的 .venv,目的地已存在且不相容時拒絕覆寫並以非零 exit code 失敗。環境從「大家記得」變成「專案自己會說明、會檢查、會拒絕」。
區分證據等級。已確認事實:表中措施與 install 腳本行為皆已實作或可直接驗證。合理推論:這組措施能縮短同類事故的發現時間;「不再發生」則需要時間與新人來驗收。
大家測的是同一份程式碼,卻根本不是在同一個執行環境裡測。
It Works on My Machine 最經典的版本,不是別人的電腦不行,而是我自己的 IDE 與 Terminal 根本住在不同世界。
故事二到此收束。下一個故事(Day 11 起)從環境層下到語言層:一個逗號,語法完全合法,卻悄悄把資料型別換掉了。