前言

前面的 2. 資料夾的建立與刪除 已經用過os.pathisdir()isfile()exists()來檢查路徑是否存在。事實上os.path的功能不只如此,它還可以取得完整路徑、分解路徑、組合路徑、查詢檔案大小

os.path包含在os模組內,匯入os模組即可使用:

import os

os.path 常用函式

函式說明
abspath()傳回檔案完整的路徑名稱。
basename()傳回路徑名稱最後的檔案或路徑名稱。測試的是檔案會傳回檔名,測試的是路徑會傳回路徑。
dirname()傳回指定檔案完整的目錄路徑,dirname(__file__)則可以取得目前的目錄路徑。
exists()檢查指定的檔案或路徑是否存在。
getsize()取得指定檔案的大小 (Bytes)。
isabs()檢查指定路徑是否為完整路徑名稱。
isfile()檢查指定路徑是否為檔案。
isdir()檢查指定路徑是否為目錄。
split()分割檔案路徑名稱為目錄路徑和檔案。
splitdrive()分割檔案路徑名稱為磁碟機和檔案路徑名稱。
join()將路徑和檔案名稱結合為完整路徑。

exists() 與 getsize() 函式

exists()檢查指定的檔案或路徑是否存在,getsize()則可取得檔案大小(單位為位元組 Bytes)。

[簡例] 檢查<osexists.py>檔案是否存在,若存在則顯示完整路徑名稱並計算檔案大小。(檔名:osexists.py

[結果]

完整路徑名稱:C:\example\ch09\osexists.py
檔案大小: 207

一定要先確認存在再取大小

對不存在的檔案呼叫os.path.getsize()會產生FileNotFoundError
養成「exists()檢查,再做後續動作」的習慣,或搭配 5. 例外處理 包在try裡。

dirname() 函式

dirname()傳回指定檔案完整的目錄路徑。特別的是,dirname(__file__)可以取得程式檔本身所在的目錄路徑

import os
cur_path = os.path.dirname(__file__)     # 取得目前目錄路徑
print("現在目錄路徑:" + cur_path)

os.getcwd()os.path.dirname(__file__) 的差別

寫法取得的是
os.getcwd()執行程式時所在的工作目錄
os.path.dirname(__file__)程式檔本身所在的目錄

兩者常常相同,但如果在別的目錄下執行程式(例如python C:\proj\main.py),兩者就會不一樣。
要讀取跟程式放在一起的資料檔時,用dirname(__file__)才可靠。

路徑的分解與組合

split()把路徑拆成「目錄」與「檔名」兩部分,splitdrive()拆成「磁碟機」與「路徑」,而join()則是反過來把它們組合成完整路徑。

[簡例] 取得最後的檔案或路徑名稱、目前檔案目錄路徑、偵測是否為目錄、將路徑分解為路徑和檔名、取得磁碟機名稱以及路徑組合。(檔名:ospath.py

[結果]

最後的檔案或路徑名稱:ospath.py
目前檔案目錄路徑:C:\example\ch09
是否為目錄: False
目錄路徑:C:\example\ch09
檔名:ospath.py
磁碟機:C:
路徑名稱:\example\ch09\ospath.py
組合路徑= C:\example\ch09\ospath.py

說明

  1. split()回傳一個含兩個元素的 tuple,因此可以用fullpath, fname = ...同時接收。
  2. splitdrive()同樣回傳兩個元素,第一個是磁碟機代號(含冒號,如C:)。
  3. join()會自動補上正確的路徑分隔符號,不需要自己加\

為什麼要用 join() 而不是字串相加

初學者常直接用+把路徑接起來,但這樣有兩個問題:

# ❌ 自己拼接:要自己處理分隔符,還不跨平台
path = "C:\\data" + "\\" + "file.txt"
 
# ✅ 用 join:自動處理,Windows 用 \、Linux/macOS 用 /
path = os.path.join("C:\\data", "file.txt")

實測結果:

os.path.join(r'C:\data', 'sub', 'file.txt')
# → 'C:\\data\\sub\\file.txt'

⚠️ join() 遇到絕對路徑會丟棄前面的片段

這是很容易踩到的陷阱:

os.path.join(r'C:\data', r'\abs', 'file.txt')
# → 'C:\\abs\\file.txt'    ← C:\data 整段不見了!

因為\abs開頭是分隔符,被視為絕對路徑join()會從它重新開始組合。
組合路徑時,後面的片段不要以\/開頭

補充: splitext() 分離副檔名

書上沒有提到,但實務上很常用 —— os.path.splitext()可以把檔名與副檔名分開:

os.path.splitext("C:\\example\\ospath.py")
# → ('C:\\example\\ospath', '.py')

想批次改副檔名、或依副檔名分類檔案時很方便。


相關主題與延伸閱讀