批量重命名需确保路径完整可用,优先用pathlib.Path避免编码问题,先校验再执行,关键数据应备份,跨文件系统操作不原子且有风险。

用 os.rename 批量改名时,路径拼错直接报错 FileNotFoundError
很多人写完循环就跑,结果卡在第一个文件——因为 os.rename 要求源路径和目标路径都必须是完整、可访问的绝对或相对路径。只传文件名,它默认在当前工作目录找,而你可能在别处遍历。
实操建议:
- 统一用
os.path.join或pathlib.Path /拼接路径,别手拼字符串 - 先用
print()打印出要重命名的每一对路径,确认无误再取消注释os.rename - 如果原文件在子目录,记得遍历时保留目录层级,否则会把所有文件挪到当前目录
示例(安全第一):
import os
for file in os.listdir("data"):
if file.endswith(".txt"):
old = os.path.join("data", file)
new = os.path.join("data", "backup_" + file)
print(f"将重命名: {old} → {new}") # 先看,不执行
# os.rename(old, new)
用 pathlib.Path 改后缀更直观,但 .with_suffix() 不会覆盖原文件
.with_suffix() 只生成新路径对象,不会自动重命名。新手常以为调用它就完事了,结果文件纹丝不动。
立即学习“Python免费学习笔记(深入)”;
实操建议:
-
.with_suffix()必须配合.rename()才生效,且目标路径不能已存在,否则抛FileExistsError - 想保留原后缀逻辑(比如 .log.bak → .log),得先用
.stem提取主名,再拼新后缀 - 批量处理前建议先检查是否已有同名目标文件,避免意外覆盖
示例(改 .log 为 .txt):
from pathlib import Path
for p in Path("logs").glob("*.log"):
new_p = p.with_suffix(".txt")
if not new_p.exists():
p.rename(new_p)
else:
print(f"跳过: {new_p} 已存在")
Windows 下重命名含中文或特殊字符的文件,os 和 pathlib 行为一致但编码不敏感
Python 3 默认用系统编码读取目录(Windows 通常是 GBK),但如果文件名实际是 UTF-8 编码(比如从 Linux 同步过来),os.listdir() 可能返回乱码或 UnicodeDecodeError。而 pathlib 在多数场景下更鲁棒。
实操建议:
- 优先用
pathlib.Path.glob()或.iterdir(),它们对 Unicode 文件名兼容性更好 - 避免用
os.listdir()+ 字符串过滤中文名,改用str(p.name).startswith("报告")这类方式 - 如果真遇到编码异常,不要强行 decode/encode,先确认文件系统来源;必要时用
os.scandir()获取原始字节名再解码
批量重命名中途失败,没有回滚机制,手动恢复极麻烦
一旦循环执行到一半出错(比如权限不足、磁盘满、目标名冲突),前面的文件已经改过,后面没改,状态不一致。没有事务,也没有“撤销”操作。
实操建议:
- 重命名前,把所有“旧→新”映射存进列表,先全量校验(是否存在、是否冲突),通过再执行
- 对关键数据,加一层备份:用
shutil.copy2()复制原文件并加.bak后缀,再重命名 - 别依赖
try/except吞掉错误继续跑——至少记录失败项,否则你根本不知道哪几个漏了
最容易被忽略的一点:重命名不是原子操作,跨文件系统移动(比如从 C: 到 D:)本质是复制+删除,中间断电就丢数据。真要保险,就别跨盘操作。


















