os.rename重命名单个文件时源和目标路径必须完整,否则报OSError;批量操作需先筛选再重命名;Windows跨磁盘需用shutil.move;处理中文等特殊字符推荐pathlib.Path。

os.rename 重命名单个文件时路径必须完整
很多人直接传文件名过去,结果报 OSError: [Errno 2] No such file or directory——因为 os.rename 不接受相对路径简写,源和目标都得是绝对路径或至少同级的相对路径。它不帮你自动补当前目录,也不会从 PYTHONPATH 或环境里找。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 用
os.path.join(os.getcwd(), "old.txt")拼出完整路径,别手敲 - 目标路径如果只改名字、不换目录,优先用
os.path.dirname(src)提取原目录,再拼新文件名 - 务必先用
os.path.exists(src)和os.path.exists(dst)检查源是否存在、目标是否已存在(否则会静默覆盖)
批量重命名前必须区分“改名逻辑”和“文件筛选”
常见错误是把所有文件一股脑丢进循环,结果图片、日志、临时文件全被重命名,甚至把 .git 目录也拖进去了。真正安全的批量操作,一定是两步:先精确选中要处理的文件,再统一应用规则。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 用
glob.glob("*.jpg")或pathlib.Path(".").glob("2024_*.log")显式限定后缀/模式,别用os.listdir()全扫 - 过滤时加一层
if f.is_file()(pathlib)或os.path.isfile(f)(os),跳过目录和符号链接 - 重命名逻辑尽量抽成函数,比如
def make_new_name(old: str) -> str:,方便调试和复用
Windows 下 os.rename 无法跨磁盘移动文件
在 Windows 上执行 os.rename("C:/a.txt", "D:/b.txt") 会直接抛 OSError: [WinError 17] The system cannot move the file to a different disk drive。这不是权限问题,是 NTFS 底层限制:rename 是原子重命名,不是复制+删除。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 检测是否跨驱动器:用
os.path.splitdrive(src)[0]和os.path.splitdrive(dst)[0]对比盘符 - 跨盘场景必须改用
shutil.move(src, dst),它内部会自动 fallback 到 copy + unlink - 注意
shutil.move在 Linux/macOS 下仍调用os.rename(快),所以不用额外判断系统,但得确保目标目录存在(shutil.move不自动创建父目录)
中文文件名、空格、特殊字符导致脚本失败
脚本在自己电脑跑得好好的,一到同事机器上就卡在某个文件,报 UnicodeEncodeError 或 FileNotFoundError——大概率是路径含中文、全角空格、emoji 或控制字符。Python 3 虽默认用 UTF-8,但终端编码、文件系统挂载参数、甚至 IDE 的运行配置都可能干扰。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 用
pathlib.Path替代字符串拼接路径,它对 Unicode 更鲁棒 - 打印调试时用
repr(str(p))查看真实字节,比如'文件名.txt'和'\u6587\u4ef6\u540d.txt'是否一致 - 避免用
os.system("ren ...")或subprocess.run调系统命令处理中文路径,容易因 shell 编码失配崩溃
最麻烦的其实是“用户以为文件名没变,其实多了不可见字符”,比如 BOM、零宽空格。批量脚本上线前,最好拿一个带这类字符的真实文件测一遍。










