用os.listdir() + os.rename()最稳,先获取文件列表并过滤子目录,用os.path.splitext()拆分再拼新路径,注意绝对路径、异常捕获、Windows文件锁及大小写重命名技巧,配合日志避免中断丢失。

用 os.listdir() + os.rename() 最稳,别碰 glob
直接遍历目录改扩展名,os.listdir() 比 glob.glob() 更可靠——后者在路径含特殊字符或编码异常时容易漏文件或报 UnicodeDecodeError。重点不是“快”,而是“一个不落、不出错”。
实操建议:
- 先用
os.listdir()获取原始文件名列表,过滤掉子目录(用os.path.isfile()判定) - 对每个文件,用
os.path.splitext()拆出 basename 和旧扩展名,拼新路径时只换后缀,保留原名和目录结构 - 务必用绝对路径或切换到目标目录再操作,避免因当前工作目录不同导致
FileNotFoundError - 加一层
try/except捕获OSError,打印失败文件和错误原因,别让一个文件卡死整个批量流程
Windows 下重命名 .txt → .log 会报错?检查文件是否被占用
常见现象:PermissionError: [WinError 32] 另一个程序正在使用此文件。Windows 锁文件比 Linux 严格得多,尤其记事本、VS Code、IDEA 默认会独占打开的文本文件。
解决办法:
立即学习“Python免费学习笔记(深入)”;
- 关掉所有可能打开这些文件的编辑器,包括后台隐藏的进程(任务管理器里看
Code.exe、notepad.exe) - 用
handle.exe(Sysinternals 工具)查具体哪个进程占用了某文件:handle.exe -a "xxx.txt" - 如果只是临时改扩展名,且不介意内容,可用
shutil.move()替代os.rename(),它在跨文件系统时更健壮,且对锁文件的容忍略高(但非万能)
想把 .JPG 改成 .jpg?大小写敏感要小心
Linux/macOS 文件系统区分大小写,os.rename("a.JPG", "a.jpg") 是合法操作;但 Windows 默认不区分,直接 rename 会报 OSError: [WinError 183](无法创建已存在的文件)。
正确做法:
- Windows 下先重命名成中间名(如加个下划线),再 rename 成目标名:
os.rename("a.JPG", "a._jpg"); os.rename("a._jpg", "a.jpg") - 或者统一走
shutil.move(),它内部会处理这种“同名不同大小写”的场景 - 判断平台用
os.name == "nt",别依赖sys.platform,更准
一次性改上千个文件,中途断了怎么办?加个日志记录
没日志的批量操作等于裸奔。不推荐用 print 打印到控制台——关掉终端就没了;也不要用单个 log 文件追加写,崩溃时可能丢最后几行。
轻量可靠方案:
- 每成功改一个,往一个纯文本记录文件写一行:
old_name\tnew_name,用open(..., "a", newline="")并手动.flush() - 运行前先读这个记录文件,构建已处理集合,跳过它们(注意:仅适用于“确定不会重复处理”的场景)
- 更稳妥的是用
pathlib.Path().with_suffix()构造新路径,它比字符串拼接更安全,自动处理多点扩展名(如file.tar.gz→file.tar.bz2需谨慎,with_suffix()只换最后一个点后的部分)
真正麻烦的从来不是代码行数,是搞清你要改的是“最后那个点之后”还是“全部点之后”,以及 Windows 上那个看不见的文件锁。


















