Python安全删除目录树需先修改只读权限再递归删除,推荐用shutil.rmtree配合onerror回调函数(如remove_readonly)处理PermissionError,该方法跨平台有效且避免shell命令风险。

Python 安全删除目录树(含只读文件)的关键是:先修改文件权限,再递归删除。直接调用 shutil.rmtree() 在遇到只读文件时会失败(特别是在 Windows 上),但只需配合一个简单的错误处理函数就能可靠解决。
使用 shutil.rmtree + onerror 参数
这是最常用且推荐的方式。通过 onerror 回调函数捕获权限错误(如 PermissionError 或 OSError),临时赋予写权限后再重试删除。
示例代码:
import os import stat import shutildef removereadonly(func, path, ): """强制移除只读文件或目录""" os.chmod(path, stat.S_IWRITE) # 设为可写 func(path) # 再次执行原操作(如 os.remove 或 os.rmdir)
安全删除整个目录树
shutil.rmtree("path/to/dir", onerror=remove_readonly)
兼容 Windows 和类 Unix 系统
上述方法在 Windows 和 Linux/macOS 均有效。Windows 下只读属性常导致删除失败;Linux/macOS 中若目录无写权限(chmod -w)也会触发类似问题。使用 stat.S_IWRITE 是跨平台安全的写权限标志,不会误开其他权限。
立即学习“Python免费学习笔记(深入)”;
注意点:
- 不要用
os.system("rm -rf")或subprocess调用 shell 命令——不跨平台、有注入风险、难调试 - 避免手动遍历 +
os.remove——容易遗漏或顺序错误(必须从里往外删) -
onerror函数签名固定为(func, path, exc_info),第三个参数是异常信息元组,通常用不到
更健壮的版本(带日志和异常细化)
生产环境建议加简单日志和错误分类,便于排查非权限类失败(如被进程占用):
import os import stat import shutil import logginglogger = logging.getLogger(name)
def robust_remove_readonly(func, path, exc_info): if not os.path.exists(path): return try:
尝试解除只读
os.chmod(path, stat.S_IWRITE | stat.S_IREAD | stat.S_IEXEC) func(path) except Exception as e: logger.warning(f"仍无法删除 {path}: {e}")shutil.rmtree("target_dir", onerror=robust_remove_readonly)
替代方案:pathlib(Python 3.4+)
如果你偏好 pathlib,它本身不提供递归删除,但可以封装 shutil.rmtree 并复用上面的 onerror:
from pathlib import Path import shutildef safe_rmtree(p: Path): if p.is_dir(): shutil.rmtree(p, onerror=remove_readonly)
safe_rmtree(Path("my_folder"))
不复杂但容易忽略:只读问题本质是文件系统权限控制,不是 Python 的限制。只要提前“松绑”,标准库就能干净完成任务。










