shutil.rmtree()是python标准库中递归删除整个目录树的最直接方法,需确保路径为目录、处理只读文件权限、并谨慎校验路径以防误删。

用 shutil.rmtree 删除整个目录树最直接
Python 标准库的 shutil.rmtree 就是为此设计的:它会递归删除指定路径下的所有文件和子目录。不需要自己写遍历逻辑,也比 os.walk + os.remove 组合更可靠。
常见错误是传入一个文件路径——shutil.rmtree 只接受目录,传文件会抛出 OSError: [WinError 5] 拒绝访问(Windows)或 NotADirectoryError(Unix-like)。务必先用 os.path.isdir 或 pathlib.Path.is_dir() 判断。
- 默认不处理只读文件(比如 Git 生成的 .git/ 下某些文件),会报
PermissionError - 可传
onerror回调来修复权限后重试,例如:def handle_remove_readonly(func, path, _): import os os.chmod(path, stat.S_IWRITE) func(path) - Python 3.12+ 支持
missing_ok=True参数,路径不存在时不报错;旧版本需手动检查os.path.exists
需要跳过特定子目录时用 os.walk + 手动过滤
如果不能删整个目录树,比如要保留 .git 或 __pycache__,就得自己控制遍历过程。此时 os.walk 的 topdown=True(默认)配合 dirs[:] = [...] 原地修改子目录列表,是最安全的做法。
别在循环里直接 del dirs[0] 或 dirs.pop()——这会破坏 os.walk 内部迭代器状态,导致部分子目录被跳过。
- 按需过滤:在每次
for root, dirs, files in os.walk(...)循环开头,写dirs[:] = [d for d in dirs if d != ".git"] - 删除文件优先于删除目录:先遍历
files并os.remove,再对dirs中剩余目录调用os.rmdir(注意:空目录才能rmdir) - 路径拼接务必用
os.path.join(root, name)或Path(root) / name,避免硬拼"{root}/{name}"在 Windows 上出错
跨平台路径处理建议统一用 pathlib.Path
混合使用 os.path 和字符串拼接容易在不同系统上出问题,尤其是路径分隔符和 drive letter(如 C:\)。pathlib 自动适配,语义也更清晰。
例如判断是否为要排除的目录:Path(root).name == ".git" 比 os.path.basename(root) == ".git" 更直观;构造目标路径:Path(root) / f 比 os.path.join(root, f) 少出错。
-
Path.unlink(missing_ok=True)(3.8+)替代os.remove,省去存在性检查 -
Path.rmdir()要求目录为空,删前可用any(Path(root).iterdir())判断 - 递归删除单个文件?
Path(file).unlink()即可,无需额外逻辑
权限与符号链接的坑必须提前识别
Linux/macOS 上遇到 PermissionError: [Errno 13] Permission denied 不一定是权限不够,很可能是目标是符号链接指向不可写位置,或者父目录无执行(x)权限(导致无法进入目录)。Windows 上则常因文件被进程占用(如日志文件正被打开)。
-
shutil.rmtree默认不跟随符号链接(即只删 link 文件本身,不删目标),符合大多数预期;若需跟随,得自己实现遍历并用Path.resolve() - 强制删除前,建议加
try/except捕获PermissionError、FileNotFoundError等,并记录失败路径——静默失败比中断更危险 - 生产环境慎用递归删除,尤其当路径来自用户输入时,务必做白名单校验或限制根目录(如只允许在
/tmp或项目内操作)
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











