课程库 › AI 主线 › 文件与自动化脚本 › 第 4 课
路径与批量操作 —— pathlib:整理文件夹的魔法
普通课约 55 分钟
本课导读
前三课你已经能对付单个文件,但自动化的真正威力在批量:一次重命名一百张照片、把散落的文件按类型归档、扫出文件夹里所有的 CSV——这些手工要一下午的活,代码十行。本课学标准库 pathlib:把"路径"变成一个会干活的对象(U1.2 的知识马上有用),配合通配符扫描和批量循环,凑齐下一课项目课的全部零件。预计 55 分钟。
Path:路径也是对象
路径就是文件的"住址",比如 inbox/报告.txt。老派写法把它当字符串拼来拼去,现代写法用 pathlib 的 Path 类——住址升级成对象,自带一身方法:
要点速记:
Path("路径")造对象;属性答"它叫什么、在哪"(name/stem/suffix/parent),方法干活(exists/mkdir/read_text/write_text)mkdir(exist_ok=True)——建文件夹,已存在也不报错(不加这参数,重复运行就崩)write_text/read_text是 open+with 的一行速写,小文件超顺手(大文件、追加模式仍用上节课的 with open)
拼路径也告别字符串加法——斜杠运算符:
Windows 用反斜杠、Mac/Linux 用正斜杠——字符串手拼必踩坑,/ 运算符替你摆平。这是 Path 对象最讨喜的语法糖。
扫描文件夹:iterdir 与 glob
批量操作第一步永远是"先拿到文件清单"。两件工具:
iterdir()全都要;glob("*.pdf")按模式筛,*是"任意一串字符"的通配符- 两者给出的都是 Path 对象的流水线——直接 for,或
list()接住、sorted()排好 - 进阶一嘴:
glob("**/*.txt")能连子文件夹一起搜(**= 任意层目录),将来整理深层目录用得上
批量改名:rename
散装知识齐了,上批量连招。给全部 PDF 加上统一前缀:
p.rename(新Path) 一步完成改名(新路径换了文件夹就是移动——改名和搬家是同一个动作)。注意套路:新名字用旧对象的零件拼(p.parent 定位置、p.stem/p.suffix/p.name 拼名字),这样批量跑起来每个文件各得其所。
说明
批量操作的职业规矩:先"彩排"再动手。把 rename 那行注释掉、只 print 出"将要怎么改",人眼确认无误再放行——批量改错一百个文件,可比改对一个文件快多了。下一课的项目里这条规矩是硬性验收项。
组合拳预演:按类型归档
下一课项目的核心动作,先小规模练一遍——把文件按后缀搬进对应子文件夹:
新零件 p.is_dir():判断"这是文件夹吗"(对应的 p.is_file() 判断是文件)——批量扫描时先分清鱼和渔网,避免把文件夹当文件搬。
✍️ 练习
练习 1:文件档案卡
对 docs 文件夹里的每个文件打印一行档案:名字(后缀)- 字数。(stat().st_size 可以拿字节数,这里用 len(read_text()) 数字符即可。)
✅ 参考答案
from pathlib import Path
Path("docs").mkdir(exist_ok=True) # 单独运行本答案时确保道具在场
(Path("docs") / "周报.txt").write_text("本周完成三件事", encoding="utf-8")
for p in sorted(Path("docs").iterdir()):
text = p.read_text(encoding="utf-8")
print(f"{p.stem}({p.suffix})- {len(text)} 字")
练习 2:截图猎人
shots 文件夹里混着各种文件。找出所有 png,改名成 截图-01.png、截图-02.png……(按文件名排序编号,enumerate 上场),其他文件不许动。
💡 提示
for i, p in enumerate(sorted(folder.glob("*.png")), 1): 拿到序号和路径;新名字 f"截图-{i:02d}.png"(:02d 补零成两位)。
✅ 参考答案
from pathlib import Path
folder = Path("shots")
folder.mkdir(exist_ok=True) # 单独运行本答案时确保道具在场
for i, p in enumerate(sorted(folder.glob("*.png")), 1):
new_name = f"截图-{i:02d}.png"
p.rename(folder / new_name)
print(f"{p.name} → {new_name}")
print([p.name for p in sorted(folder.iterdir())])
练习 3:彩排模式(挑战)
给练习 2 的改名脚本加一个 dry_run 开关(默认 True):彩排模式只打印"将改名:旧 → 新",不真动文件;dry_run=False 才真改。两种模式各跑一次,验证彩排后文件原封不动。
✅ 参考答案
from pathlib import Path
Path("shots2").mkdir(exist_ok=True) # 单独运行本答案时确保道具在场
def rename_shots(folder, dry_run=True):
for i, p in enumerate(sorted(Path(folder).glob("*.png")), 1):
new_name = f"截图-{i:02d}.png"
if dry_run:
print(f"[彩排] 将改名:{p.name} → {new_name}")
else:
p.rename(p.parent / new_name)
print(f"已改名:{p.name} → {new_name}")
rename_shots("shots2") # 先彩排
print([p.name for p in sorted(Path("shots2").iterdir())]) # 原封不动
rename_shots("shots2", dry_run=False) # 确认无误,放行
print([p.name for p in sorted(Path("shots2").iterdir())])
dry_run 是自动化脚本的行业标配参数(很多命令行工具的 --dry-run 就是它)——批量操作前先彩排,这个习惯值钱一辈子。
📝 随堂测验
1. Path 对象拼路径的推荐写法是?
2. p = Path("inbox/报告.txt"),p.stem 和 p.suffix 分别是?
3. 只想要文件夹里的全部 CSV 文件,用哪个?
4. mkdir(exist_ok=True) 里这个参数解决什么问题?
5. 批量重命名一百个文件前,最专业的动作是?
本课小结
Path把路径变对象:属性答"叫什么在哪"(name/stem/suffix/parent),方法干活(mkdir/exists/read_text/rename);拼路径用/- 扫描:
iterdir()全要,glob("*.pdf")按通配符筛;is_dir()/is_file()分清鱼和渔网 - 批量套路:扫描 → 用旧对象零件拼新名 →
rename;改名与移动是同一动作 - 职业规矩:批量操作先彩排(dry_run),
exist_ok=True让脚本可重复运行
零件集齐。下一课项目实战:把一个 30 个文件的灾难现场文件夹,一键整理成归档目录 + 清单报表——作品集材料 +1。
划选正文任意文字可高亮、批注或加入复习卡
讨论
载入中…