os.rename是Python中重命名单个文件的底层方法,仅支持同设备“原地改名”,需确保源存在、目标目录已建、权限充足;跨设备应改用shutil.move。

os.rename 重命名单个文件的基本用法
os.rename 是 Python 标准库中直接操作文件系统重命名的底层方法,它不处理路径解析、不存在目录或跨文件系统移动等复杂逻辑,只做“原地改名”。调用时必须确保源路径 src 存在、目标路径 dst 所在目录已存在,且当前用户有写权限。
常见错误现象:OSError: [Errno 2] No such file or directory(源文件不存在)、OSError: [Errno 13] Permission denied(权限不足)、OSError: [Errno 18] Invalid cross-device link(跨磁盘移动时报错,此时 os.rename 失效)。
实操建议:
- 始终用
os.path.exists(src)检查源文件是否存在 - 用
os.path.dirname(dst)提取目标目录,并用os.makedirs(..., exist_ok=True)确保其存在 - 若需跨设备移动+重命名,改用
shutil.move替代 - 避免在循环中直接拼接字符串构造
dst,推荐用os.path.join或pathlib.Path
批量重命名文件时如何安全生成新文件名
真实场景中,重命名不是简单加后缀,而是按序号、时间戳、正则替换或映射表来生成新名。关键在于:**新名不能与同目录下已有文件冲突,且要保留原扩展名(除非明确要改)**。
容易踩的坑:用 enumerate 直接从 0 开始编号导致 001.jpg → 0.jpg;忽略大小写导致 Windows 下误判重复;未分离文件名与扩展名导致 report.txt.bak 变成 report_01.bak。
实操建议:
- 用
os.path.splitext(filename)拆出(name, ext),重命名时只改name部分 - 编号类命名用
f"{i:03d}"格式化,避免位数不齐 - 遍历前先收集所有待处理文件路径(用
glob.glob("*.log")或os.listdir()+os.path.isfile()过滤),再统一生成新名,防止边读边写引发路径错乱 - 如需按原始顺序重命名,显式排序:
sorted(os.listdir(dir_path)),而非依赖os.listdir的不确定返回顺序
处理中文路径、空格和特殊字符的注意事项
Windows 下中文路径、macOS 中带空格的文件名,在命令行或旧脚本里常出问题,但 Python 3.6+ 的 os.rename 原生支持 Unicode 路径,只要 Python 自身能正常读取,就无需额外编码转换。
真正的问题往往出在:手动拼接路径时混用 / 和 \;用 subprocess 调外部命令时未加引号;或日志打印时因终端编码不匹配显示为 ——但这不影响实际重命名。
实操建议:
- 一律使用
os.path.join(dir_path, old_name)构造完整路径,不要手拼dir_path + "/" + old_name - 调试时用
repr(full_path)查看真实字节序列,比直接 print 更可靠 - 如果脚本被双击运行(无终端),错误会被吞掉,务必加
try/except并写入日志文件,例如:with open("rename.log", "a", encoding="utf-8") as f: f.write(f"Failed: {src} -> {dst}\n")
为什么重命名后文件“消失”了——相对路径陷阱
最常被忽略的一点:os.rename 的两个参数都是**完整路径(absolute)或相对于当前工作目录(relative)的路径**。如果你在 /home/user/docs 下运行脚本,而目标文件夹是 ./data,那么传入 os.rename("old.txt", "new.txt") 实际会把 ./data/old.txt 改成 ./new.txt(即移到上层目录),而不是 ./data/new.txt。
这会导致文件看似“丢失”,其实是被移到了意料之外的位置。
实操建议:
- 统一转为绝对路径:
src = os.path.abspath(os.path.join(dir_path, filename)) - 目标路径也基于同一根目录构建:
dst = os.path.abspath(os.path.join(dir_path, new_filename)) - 执行前打印
src和dst(用repr()),确认两者父目录一致 - 首次批量操作前,先对 1–2 个文件做 dry-run(只打印不执行),验证逻辑
实际批量重命名的健壮性,不取决于是否用了花哨的类或 GUI,而在于每一步是否显式处理了路径、编码、冲突和异常边界。尤其当文件数超过 100,手动检查成本陡增,这些细节就成了唯一防线。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











