用 pathlib 整理水井村USR教材與巡查檔案
讓教材、逐字稿、照片與巡查紀錄各就各位,而且每一步都能先預覽、再執行。
完成本篇後,你能用
Path 建立跨平台路徑,檢查檔案與資料夾、巡覽與搜尋檔案、建立目錄、讀寫 UTF-8 文字,並設計不覆蓋原檔的安全重新命名流程。一、為什麼推薦 pathlib?
USR專案常同時保存教案、巡查CSV、長者逐字稿、活動照片與成果報告。直接用字串拼接路徑容易漏掉斜線,也會遇到Windows與其他系統的差異。pathlib 把路徑當成物件,操作更清楚。
二、建立與組合路徑
from pathlib import Path
project = Path("shuijing_usr")
lesson = project / "教材" / "Python一下_16.html"
print(project)
print(lesson)
print("檔名:", lesson.name)
print("主檔名:", lesson.stem)
print("副檔名:", lesson.suffix)
print("上層:", lesson.parent)運算子 / 會依作業系統組合路徑,不需要手動判斷斜線方向。
三、相對路徑與絕對路徑
from pathlib import Path
current = Path.cwd()
relative_path = Path("shuijing_usr") / "巡查資料"
absolute_path = relative_path.resolve()
print("目前工作目錄:", current)
print("相對路徑:", relative_path)
print("絕對路徑:", absolute_path)相對路徑會以「目前工作目錄」為起點。Thonny、Colab與終端機的工作目錄可能不同;找不到檔案時,先印出 Path.cwd()。
四、建立USR專案資料夾
from pathlib import Path
root = Path("shuijing_usr_demo")
folders = [
root / "教材",
root / "巡查資料",
root / "逐字稿" / "原始檔",
root / "逐字稿" / "確認稿",
root / "活動照片",
]
for folder in folders:
folder.mkdir(parents=True, exist_ok=True)
print("已確認資料夾:", folder)parents=True 會一併建立缺少的上層資料夾;exist_ok=True 讓既有資料夾不會造成錯誤。
五、檢查路徑是否存在
from pathlib import Path
path = Path("shuijing_usr_demo")
print("存在:", path.exists())
print("是檔案:", path.is_file())
print("是資料夾:", path.is_dir())不要只檢查 exists();同一個名稱可能是檔案也可能是資料夾,後續操作前應確認類型。
六、列出與搜尋檔案
from pathlib import Path
root = Path("shuijing_usr_demo")
print("第一層內容:")
for path in sorted(root.iterdir()):
print("-", path.name)
print("所有 CSV:")
for path in sorted(root.rglob("*.csv")):
print("-", path)| 方法 | 用途 |
|---|---|
iterdir() | 列出目前資料夾第一層 |
glob("*.txt") | 搜尋目前層符合規則的項目 |
rglob("*.csv") | 包含所有子資料夾的遞迴搜尋 |
七、讀寫UTF-8文字
from pathlib import Path
note_path = Path("shuijing_usr_demo") / "教材" / "說明.txt"
content = "水井村USR教材\n主題:從風土資料到智慧生活\n"
note_path.write_text(content, encoding="utf-8")
loaded = note_path.read_text(encoding="utf-8")
print(loaded)write_text() 預設會覆蓋既有內容,因此實際工作前要檢查目標是否存在。大量資料或逐行處理則使用 open() 與 with。
八、安全寫入:拒絕覆蓋既有檔案
from pathlib import Path
def safe_write_text(path, content):
path = Path(path)
if path.exists():
raise FileExistsError(f"目標已存在:{path}")
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(content, encoding="utf-8")
return path
target = Path("shuijing_usr_demo") / "教材" / "新教材.txt"
try:
created = safe_write_text(target, "教學內容\n")
except FileExistsError as error:
print("未寫入:", error)
else:
print("已建立:", created)九、用檔名取得基本資訊
from pathlib import Path
files = [
Path("2026-08-30_巡查_示範池A.csv"),
Path("水井三寶_白馬_確認稿.txt"),
Path("活動照片_001.JPG"),
]
for path in files:
print(
"名稱:", path.name,
"|主檔名:", path.stem,
"|副檔名:", path.suffix.lower(),
)使用 suffix.lower() 可同時處理 .JPG 與 .jpg。但只看副檔名不能保證檔案內容安全或格式正確。
十、依副檔名規劃分類
from pathlib import Path
CATEGORIES = {
".html": "教材",
".pdf": "成果報告",
".csv": "巡查資料",
".txt": "逐字稿",
".jpg": "活動照片",
".jpeg": "活動照片",
".png": "活動照片",
}
def choose_folder(path):
return CATEGORIES.get(path.suffix.lower(), "待確認")
for name in ["lesson.html", "reading.csv", "photo.JPG", "unknown.bin"]:
path = Path(name)
print(path.name, "→", choose_folder(path))未知格式放入「待確認」,不要自動刪除。分類規則也應區分原始檔、工作檔與公開版,不能只依副檔名決定公開權限。
十一、先預覽,再重新命名
下面先建立「來源→目標」計畫,不立即變更檔案。只有確認來源存在、目標不重複且位於允許資料夾時才執行。
from pathlib import Path
def build_rename_plan(folder):
folder = Path(folder)
plan = []
for number, source in enumerate(
sorted(folder.glob("*.jpg")),
start=1,
):
target = source.with_name(f"活動照片_{number:03d}.jpg")
plan.append((source, target))
return plan
def show_plan(plan):
for source, target in plan:
print(f"預覽:{source.name} → {target.name}")
plan = build_rename_plan("shuijing_usr_demo/活動照片")
show_plan(plan)十二、安全執行重新命名
def apply_rename_plan(plan, confirmed=False):
if not confirmed:
print("預覽模式:沒有變更任何檔案")
return
targets = [target for _, target in plan]
if len(targets) != len(set(targets)):
raise ValueError("計畫中有重複目標檔名")
for source, target in plan:
if not source.is_file():
raise FileNotFoundError(f"來源不存在:{source}")
if target.exists() and target != source:
raise FileExistsError(f"目標已存在:{target}")
for source, target in plan:
if source != target:
source.rename(target)
print(f"已重新命名:{source.name} → {target.name}")
apply_rename_plan(plan, confirmed=False)confirmed 改為 True。十三、建立檔案盤點報告
from collections import Counter
from pathlib import Path
def inventory(folder):
folder = Path(folder)
files = [path for path in folder.rglob("*") if path.is_file()]
extensions = Counter(
path.suffix.lower() or "(無副檔名)" for path in files
)
return files, extensions
files, extensions = inventory("shuijing_usr_demo")
print("檔案總數:", len(files))
for extension, count in sorted(extensions.items()):
print(extension, count)十四、常見錯誤檢查表
| 現象 | 可能原因 | 修正方式 |
|---|---|---|
| 找不到明明存在的檔案 | 工作目錄不同 | 先檢查 Path.cwd() |
| 文字檔出現亂碼 | 讀寫編碼不一致 | 確認來源並指定 UTF-8 |
| 同名檔被覆蓋 | 寫入前未檢查 | 使用 exists() 或排他建立模式 |
| 搜尋不到大寫.JPG | 副檔名大小寫不同 | 取 suffix.lower() 後判斷 |
| 整理後連結失效 | 外部文件仍引用舊路徑 | 先盤點依賴並輸出更名對照表 |
十五、USR實作挑戰
統計HTML、PDF、圖片及程式檔數量,輸出副檔名報告與「待確認」清單,不移動任何檔案。
規劃「原始檔、整理稿、講述者確認稿、公開版」資料夾,為每個版本設計清楚檔名,保留授權資訊。
只建立照片更名預覽與CSV對照表,人工確認沒有同名、錯序或連結依賴後才執行。
十六、與生成式AI協作
請擔任Python pathlib與資料治理助教。
我要整理USR教材、逐字稿、巡查CSV及活動照片。
請設計一個安全整理程式:
1. 第一次執行只能預覽,不可移動或刪除;
2. 不得覆蓋既有檔案;
3. 未知格式放入待確認;
4. 保留原始逐字稿與授權資料;
5. 執行前檢查重複目標與遺失來源;
6. 輸出來源、目標及結果對照表。
請先說明風險,再提供可測試的函式。pathlib讓路徑操作跨平台且容易閱讀。真正可靠的檔案整理還需要三道防線:使用副本、先預覽計畫、拒絕覆蓋既有資料。
沒有留言:
張貼留言