在 Python 開發過程中,你一定遇過以下兩種令人抓狂的錯誤:
ModuleNotFoundError: No module named 'xxx''pip' 不是內部或外部命令、可執行的程式或批次檔。
雖然它們都跟「找不到東西」有關,但背後的元兇完全不同。
這篇教學將帶你深入 Python 的「兩條路」,
徹底釐清 Python 模組路徑 (sys.path) 與 系統環境變數 (PATH) 的區別。
1. 觀念速覽:圖書館 vs. 商店街
如果把你的電腦比喻成一座城市:
A. sys.path (Python 的圖書館索書號)
- 誰在用? Python 直譯器 (當你寫
import時)。 - 找什麼? 找
.py檔案 或 套件資料夾。 - 比喻:就像你在圖書館要找一本「參考書」。你必須查閱「索書清單 (
sys.path)」,清單上列出的書架(資料夾),Python 才會走過去找。如果書架上沒有這本書,Python 就會雙手一攤說找不到。
B. os.environ['PATH'] (作業系統的商店導航)
- 誰在用? Windows/Mac/Linux 作業系統 (當你在終端機打指令時)。
- 找什麼? 找
.exe執行檔。- 基礎工具:
python.exe,pip.exe,git.exe,notepad.exe - 外部依賴:
- Tesseract OCR (
tesseract.exe):做文字辨識時必備。 - Graphviz (
dot.exe):畫流程圖時,Python 的graphviz套件會呼叫它。 - FFmpeg (
ffmpeg.exe):多媒體萬用刀。- YouTube 下載 (
yt-dlp):需要它來合併高畫質影音。 - OpenAI Whisper (語音轉文字):需要它來讀取各種格式的音訊檔並重取樣 (Resample)。
- YouTube 下載 (
- Chrome Driver (
chromedriver.exe):網頁爬蟲自動化時需要。
- Tesseract OCR (
- 基礎工具:
- 比喻:就像你在街上大喊「我要喝星巴克!」。作業系統會拿出「商店導航地圖 (
PATH)」,沿著地圖上的每一條路(資料夾)去尋找有沒有一家店叫做星巴克。如果地圖上的路都找完了還沒看到,系統就會報錯。
超級比一比
⭐ 簡單一句話:一個找
.py,一個找.exe。
| 特徵 | sys.path | os.environ['PATH'] |
|---|---|---|
| 主詞 (使用者) | Python 程式碼 (import) | 終端機 / CMD (Shell) |
| 受詞 (尋找物) | .py 模組 / Library | .exe 執行檔 / .bat 腳本 |
| 資料型態 | List (列表) | String (分號隔開的字串) |
| 常見錯誤 | ModuleNotFoundError | 'xxx' 不是內部或外部命令 |
2. 實戰演練:sys.path
讓我們直接用程式碼來看看 Python 到底去哪裡找模組。
import sys
print("=== Python 目前的搜尋路徑 (sys.path) ===")
for path in sys.path:
print(path)
# 通常你會看到:
# 1. 當前腳本所在的資料夾 (空字串 '' 或絕對路徑)
# 2. Python 安裝目錄下的 DLLs, Lib
# 3. site-packages (這是 pip install 套件安裝的地方)💡 小技巧:臨時加入搜尋路徑
如果你寫了一個 my_tool.py 放在 D:\Tools,
但不想把它安裝成套件,可以直接把它加進 sys.path:
import sys
import os
custom_tool_path = r"D:\Tools"
# 檢查是否已存在,避免重複加入
if custom_tool_path not in sys.path:
sys.path.append(custom_tool_path)
print(f"已將 {custom_tool_path} 加入搜尋路徑!")
# 現在可以直接 import 該資料夾下的 py 檔了
# import my_tool 3. 實戰演練:os.environ[‘PATH’]
接著我們來看看作業系統的環境變數。
雖然這是 OS 層級的設定,但 Python 可以透過 os 模組來讀取它。
import os
# 取得系統環境變數 PATH
# 在 Windows 上,路徑之間用分號 ';' 隔開
sys_paths = os.environ.get("PATH", "").split(';')
print(f"=== 系統 PATH 共有 {len(sys_paths)} 個搜尋路徑 ===")
# 只印出前 5 個示範,不然太多了
for p in sys_paths[:5]:
print(p)💡 如何確認 Python 找不找得到某個指令?
Python 的 shutil 模組有一個 which 函式,行為就跟 Linux 的 which 指令一樣,它會幫你去 PATH 裡面找檔案。
import shutil
# 測試:找找看 python.exe 在哪裡
python_loc = shutil.which("python")
print(f"Python 指令位置: {python_loc}")
# 測試:找找看 notepad (記事本) 在哪裡
notepad_loc = shutil.which("notepad")
print(f"Notepad 指令位置: {notepad_loc}")
# 測試:找找看一個不存在的指令
files_loc = shutil.which("super_mario")
print(f"Mario 指令位置: {files_loc}") # 應該會是 None4. 進階陷阱:當兩條路交會時 (以 OCR 為例)
這是最容易搞混的地方。有些 Python 套件(如 pytesseract 或 selenium)只是「外殼 (Wrapper)」,它們工作原理是去呼叫外部的 .exe 檔。
經典錯誤案例:Tesseract
- 你執行
import pytesseract→ 成功 (因為sys.path裡有 pytesseract 套件)。 - 你執行
pytesseract.image_to_string(img)→ 報錯! (TesseractNotFoundError)
為什麼?
因為 pytesseract 雖然載入到了 Python 記憶體中,但它底層試圖去呼叫 subprocess.Popen(['tesseract', ...])。
這時候,它依賴的是 作業系統的 PATH 來找到 tesseract.exe。
如果你的 PATH 沒設定好,就算 pip install 了一百次 pytesseract,程式還是跑不動。
解決方案
你要不是去「系統設定」把路徑加進 PATH,就是在 Python 裡指路給它看:
# 解決方案:明確告訴套件 exe 在哪裡,繞過對系統 PATH 的依賴
# pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'總結
- import 失敗 (
ModuleNotFoundError) ➡️ 檢查sys.path(是不是少裝了套件?還是路徑沒加?)。 - 執行失敗 (
xxx 不是內部指令) ➡️ 檢查os.environ['PATH'](是不是沒把 bin 或 Scripts 資料夾加入環境變數?)。
掌握這兩個觀念,能解決 90% 的 Python 環境設定問題!
推薦hahow線上學習python: https://igrape.net/30afN