這篇教學要講的是一個很常混在一起的觀念:
– `os.environ[“PATH”]`
– `sys.path.append(…)`
很多人第一次看到這兩個,都會覺得:
– 反正都是 path
– 反正都是在「讓程式找得到東西」
– 看起來只差一個是 `os.environ`,一個是 `sys.path`
但它們其實不在同一層。
最簡單的一句話是:
– `os.environ[“PATH”]`:讓作業系統找「可執行檔」
– `sys.path`:讓 Python 找「可 import 的東西」,
白話講通常就是 `.py` 檔,
或一個可被當成模組資料夾的目錄
(最常見是裡面有 `__init__.py`)
## 先用 Whisper + ffmpeg 這個例子理解
這個例子很適合,因為它剛好同時碰到兩層:
1. `whisper` 本身是一個 Python 模組
2. `ffmpeg.exe` 是一個外部可執行檔
所以你可能會遇到兩種完全不同的錯誤。
### 情況 A:Python 找不到 `whisper`
例如:
“`python
import whisper
“`
結果報:
“`text
ModuleNotFoundError: No module named ‘whisper’
“`
這代表:
– Python 解譯器找不到 `whisper` 這個模組
– 這通常是 interpreter、虛擬環境、site-packages、`sys.path` 這一層的問題
### 情況 B:`whisper` 可以 import,但跑起來找不到 `ffmpeg.exe`
例如 `whisper` 已經能 import,
但執行轉音訊時,底層 subprocess 找不到 `ffmpeg`。
這時問題通常不是 `sys.path`,而是:
– 作業系統找不到 `ffmpeg.exe`
– 也就是「作業系統搜尋可執行檔的路徑(PATH)」這一層有問題
所以同樣都是「找不到」,
但其實是兩種完全不同的找法。
## `os.environ[“PATH”]` 在做什麼
`os.environ[“PATH”]` 對應的是作業系統層的搜尋路徑。
當你在終端機輸入:
“`text
python
pip
git
ffmpeg
“`
系統會去 `os.environ[“PATH”]` 裡列出的資料夾,
一個一個找對應的執行檔。
所以它主要解決的是:
– `ffmpeg.exe` 找不找得到
– `python.exe` 找不找得到
– `pip.exe` 找不找得到
例如:
“`python
import os
print(os.environ[“PATH”])
“`
你看到的通常會是一大串資料夾路徑。
### 臨時把 `ffmpeg\bin` 加進 PATH
“`python
import os
ffmpeg_bin_path = r”C:\ffmpeg\bin”
os.environ[“PATH”] = ffmpeg_bin_path + os.pathsep + os.environ[“PATH”]
“`
注意:這裡加進 `os.environ[“PATH”]` 的是
`C:\ffmpeg\bin` 這個資料夾,
不是 `C:\ffmpeg\bin\ffmpeg.exe` 這個檔案本身。
這裡特別把 `ffmpeg_bin_path` 放在前面,
不是單純寫法習慣,
而是為了讓這個目錄裡的 `ffmpeg.exe` 取得更高優先權。
也就是說,系統之後找 `ffmpeg.exe` 時,會先找:
– `C:\ffmpeg\bin`
– 再找原本 `os.environ[“PATH”]` 裡既有的那些目錄
這在電腦上同時存在多個版本的
`ffmpeg.exe`、`dot.exe`、`python.exe` 時很有用。
如果你改寫成下面這種:
“`python
os.environ[“PATH”] += os.pathsep + ffmpeg_bin_path
“`
那就會變成把新路徑加到最後面。
這種寫法不是不能用,而是優先權比較低:
– 前面原本 PATH 裡如果已經有另一個 `ffmpeg.exe`
– 系統通常會先找到舊的那個
– 你剛加進去的版本反而不一定會被用到
所以:
– 把新路徑放前面:表示「先用我指定的這個版本」
– 把新路徑加到後面:表示「前面都找不到時再用我」
這樣做的效果是:
– 只在目前這個 Python 程序中暫時生效
– 讓這個程序之後啟動的子程序,
也能比較容易找到 `ffmpeg.exe`
這裡刻意用:
“`python
os.pathsep
“`
而不是直接硬寫 `;`。
因為:
– Windows 的 path 分隔符是 `;`
– Linux / macOS 是 `:`
所以 `os.pathsep` 比較穩。
## `sys.path.append(…)` 在做什麼
`sys.path` 是 Python 解譯器用來找模組的路徑清單。
當你寫:
“`python
import my_utils
“`
Python 不看 `os.environ[“PATH”]`,它看的是:
“`python
import sys
print(sys.path)
“`
也就是:
– 目前工作目錄
– 標準函式庫
– site-packages
– 你手動 append 的資料夾
所以它主要解決的是:
– `import whisper` 找不找得到
– `import my_utils` 找不找得到
– `import project.helpers` 找不找得到
### 臨時把自訂模組目錄加進 `sys.path`
“`python
import sys
sys.path.append(r”D:\user\Python\my_project\src”)
“`
這樣做的效果是:
– 只在目前這個 Python 程序中暫時生效
– 讓 Python 之後可以從這個目錄 import 模組
## 兩者最核心的差別
如果只用一句話區分:
– `os.environ[“PATH”]` 找的是 executable
– `sys.path` 找的是 Python module
你也可以用下面這個對照表記住。
![Python `os.environ["PATH"]`(設定 *.exe 路徑)vs `sys.path`(設定 *.py 路徑)教學:用 Whisper 與 ffmpeg 看懂兩種很像的 path - 儲蓄保險王](https://savingking.com.tw/wp-content/uploads/2026/05/20260513130826_0_8d5fb3.png)
## 為什麼這兩個看起來很像
因為它們有三個共同點:
1. 都是一串路徑
2. 都是在「找東西」
3. 都可以在程式執行時暫時修改
所以很容易被誤認成同一件事。
但它們的搜尋對象不同:
– `os.environ[“PATH”]` 是給系統找程式
– `sys.path` 是給 Python 找模組
## `No module named …` 一般優先看什麼
如果錯誤是:
“`text
ModuleNotFoundError: No module named ‘xxx’
“`
一般優先檢查這些:
1. VS Code / Notebook 選到的 interpreter 是否正確
2. 套件是否真的安裝在那個 interpreter 對應的環境
3. 專案結構是否正確
4. 啟動方式是否合理,例如要不要用 `python -m package.module`
5. 是否只是編輯器分析錯誤,需要 `python.analysis.extraPaths`
不是先去改 `os.environ[“PATH”]`。
## `ffmpeg not found` 一般優先看什麼
如果是 `whisper` 類似工具能 import,
但執行時找不到 `ffmpeg`,那優先看的是:
1. `ffmpeg.exe` 是否真的存在
2. 它的 `bin` 目錄是否在系統 PATH 裡,也就是目前程序看到的 `os.environ[“PATH”]` 裡
3. 目前 Python 程式是否有把 `ffmpeg_bin_path` 臨時加進 `os.environ[“PATH”]`
這時通常不是 `sys.path` 的問題。
## 除了 `ffmpeg.exe`,還有哪些常見的 PATH 類外部工具?
如果 Python 套件本身可以 import,
但執行時還要再呼叫外部工具,
那常常就是 `os.environ[“PATH”]` / 系統 PATH 這一層。
比較常見、也很適合拿來理解的例子有:
– `ffmpeg.exe`
– `graphviz.exe`(很多時候實際缺的是 `dot.exe`)
– `dot.exe`
– `tesseract.exe`
– `pandoc.exe`
– `git.exe`
其中前面幾個最典型:
– `ffmpeg.exe`:影音轉檔、Whisper、moviepy、pydub
– `graphviz.exe` / `dot.exe`:流程圖、依賴圖、Graphviz 輸出
– `tesseract.exe`:OCR,常見於 `pytesseract`
### PaddleOCR 算不算這一類?
通常不算典型的 `os.environ[“PATH”]` 類外部 exe 依賴。
因為 PaddleOCR 比較常見的依賴是:
– `paddleocr`
– `paddlepaddle`
– GPU / CUDA / cuDNN
– DLL 或底層 runtime
– 模型檔
也就是說,PaddleOCR 比較常見的是 Python 套件與 runtime 依賴,
不是像 `tesseract.exe` 那樣,先去系統 PATH 裡找一個外部執行檔。
## `sys.path.append(…)` 能不能用
可以,但通常是臨時補丁,不是最漂亮的正式解法。
它適合:
– notebook
– 快速測試
– 一次性腳本
– 臨時驗證模組路徑
不太適合:
– 長期正式專案
– 多人協作
– 結構已固定的 package 專案
因為它會讓 import 規則散落在程式內部。
## `os.environ[“PATH”]` 能不能在程式內改
可以,但同樣屬於程序內暫時修補。
例如:
“`python
import os
ffmpeg_bin_path = r”C:\ffmpeg\bin”
os.environ[“PATH”] = ffmpeg_bin_path + os.pathsep + os.environ[“PATH”]
“`
這種做法很適合:
– 單一腳本
– notebook
– 臨時測試
– 你知道某個外部工具只差最後一步路徑沒接上
但如果是正式環境,通常更建議:
– 直接把 `ffmpeg\bin` 加到系統 PATH
– 讓所有終端機 / 工具都能共用
## 這個例子裡的三層關係
拿 `whisper` 當例子,可以把整件事拆成三層:
### 第 1 層:VS Code / Notebook 選哪個 Python
這一層常和:
– `python.defaultInterpreterPath`
– 實際選到的 interpreter
有關。
如果這裡就選錯了,後面很多事情都會錯。
### 第 2 層:Python 能不能 import 模組
這一層常和:
– site-packages
– `sys.path`
– 專案結構
有關。
例如:
– `import whisper`
– `import my_utils`
### 第 3 層:被呼叫的外部工具能不能被系統找到
這一層常和:
– `os.environ[“PATH”]`
– 系統環境變數 PATH
有關。
例如:
– `ffmpeg.exe`
– `git.exe`
– `pandoc.exe`
## 最實用的一句判斷
如果你看到的是:
“`text
No module named …
“`
先想:
– 這是 Python 找模組失敗
– 優先看 interpreter、環境、`sys.path`
如果你看到的是:
“`text
ffmpeg not found
“`
先想:
– 這是系統找可執行檔失敗
– 優先看 `os.environ[“PATH”]` / 系統 PATH
## 最後一句話
`os.environ[“PATH”]` 和 `sys.path` 看起來都像「路徑清單」,
但它們分別服務兩個不同世界:
– `os.environ[“PATH”]` 是作業系統的世界
– `sys.path` 是 Python import 的世界
用 `whisper` 與 `ffmpeg` 這個例子去記,通常最不容易搞混:
– `whisper` 是 module,所以偏 `sys.path`
– `ffmpeg.exe` 是 executable,所以偏 `os.environ[“PATH”]`
推薦hahow線上學習python: https://igrape.net/30afN



![Python TQC考題910 學生基本資料, print(line.decode(“utf-8”)), if line.decode(“utf-8″).split()[2] ==”0”: female += 1 Python TQC考題910 學生基本資料, print(line.decode(“utf-8”)), if line.decode(“utf-8″).split()[2] ==”0”: female += 1](https://i2.wp.com/savingking.com.tw/wp-content/uploads/2022/05/20220514163621_72.png?quality=90&zoom=2&ssl=1&resize=350%2C233)






近期留言