0

0

如何递归创建目录但不抛 FileExistsError(exist_ok)

舞姬之光

舞姬之光

发布时间:2026-01-24 18:27:09

|

529人浏览过

|

来源于php中文网

原创

管用,但仅当路径已存在且为目录时静默跳过;若路径是文件或父级为文件,仍抛FileExistsError或OSError。

如何递归创建目录但不抛 fileexistserror(exist_ok)

Python 中 os.makedirsexist_ok 参数到底管不管用?

管用,但只在「目标路径是目录且已存在」时生效;如果路径已存在且是文件,os.makedirs 仍会抛 FileExistsError。这是最常被误解的一点——很多人以为设了 exist_ok=True 就能“完全静默”,结果在部署脚本里突然崩了。

常见错误现象:FileExistsError: [Errno 17] File exists: '/path/to/log',而 /path/to/log 实际上是个普通文件(比如日志文件被提前 touch 出来了),不是目录。

  • exist_ok=True 不会覆盖、不尝试删除、不重命名,它只跳过「创建目录」动作本身
  • 如果父路径中某一级是文件(比如 /tmp 被误写成文件),也会立即报错,不会走到最后一级
  • Python 3.2+ 才支持该参数;旧版本需手动 try/except

想真正静默建目录,得先判断路径类型

安全做法是:先用 os.path.exists 检查,再用 os.path.isdir 确认是不是目录,最后决定是否调用 os.makedirs。绕过 exist_ok 的语义盲区。

示例逻辑:

import os
<p>def safe_makedirs(path):
if os.path.exists(path):
if not os.path.isdir(path):
raise NotADirectoryError(f"Cannot create directory: {path} exists and is not a directory")</p><h1>已是目录,无需操作</h1><pre class="brush:php;toolbar:false;">    return
os.makedirs(path, exist_ok=True)

  • 不要只靠 os.path.isdir(path) 判断——路径不存在时它也返回 False,容易误删或跳过
  • 异常类型选 NotADirectoryError 更准确,比泛用 Exception 更利于下游捕获处理
  • 如果业务允许覆盖(极少见),需显式 os.unlink(path) + os.makedirs,但务必加注释说明风险

替代方案:pathlib.Path.mkdirexist_ok 行为一致吗?

行为完全一致:Python 3.4+ 的 pathlib.Path.mkdir(parents=True, exist_ok=True) 同样只对「已存在且为目录」静默,遇到同名文件照样抛 FileExistsError

Chromox
Chromox

Chromox是一款领先的AI在线生成平台,专为喜欢AI生成技术的爱好者制作的多种图像、视频生成方式的内容型工具平台。

下载

所以换写法不解决问题,只是语法糖。但 pathlib 在组合路径时更健壮(自动处理斜杠、跨平台),推荐用于新项目:

from pathlib import Path
<p>p = Path("/var/log/myapp")
p.mkdir(parents=True, exist_ok=True)  # 同样不解决“路径是文件”的情况
  • parents=True 是必须的,否则父目录不存在时直接失败(os.makedirs 默认就是递归)
  • 不能用 p.mkdir(exist_ok=True) 代替 p.parent.mkdir(...) 来建父目录——它只作用于 p 自身
  • os.makedirs 一样,不处理权限(mode 参数受 umask 影响),生产环境建议显式设 mode=0o755

Shell 场景下怎么避免 mkdir -p 报错?

Linux/macOS 的 mkdir -p 本身就不抛错——它遇到已存在目录直接忽略,遇到同名文件则报 mkdir: cannot create directory ‘xxx’: File exists,行为和 Python 完全对应。

所以 shell 脚本里也得防御性检查:

if [ -e "$DIR" ] && [ ! -d "$DIR" ]; then
  echo "Error: $DIR exists but is not a directory" >&2
  exit 1
fi
mkdir -p "$DIR"
  • 别用 [ -d "$DIR" ] || mkdir -p "$DIR" ——当 $DIR 不存在时,-d 返回 false,会执行 mkdir;但当它是文件时,-d 也返回 false,同样会执行 mkdir 并失败
  • [ -e ][ -d ] 必须分开判断,顺序不能反(先 -e-d
  • zsh/bash 都支持,但 dash(/bin/sh 默认)不支持 [[,坚持用 [ 更稳妥

实际用的时候,最容易被忽略的是:你写的函数或脚本,可能跑在别人已经预置了同名文件的环境里。这时候 exist_ok=True 不是银弹,而是个温柔的陷阱。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
macOS怎么切换用户账户
macOS怎么切换用户账户

在 macOS 系统中,可通过多种方式切换用户账户。如点击苹果图标选择 “系统偏好设置”,打开 “用户与群组” 进行切换;或启用快速用户切换功能,通过菜单栏或控制中心的账户名称切换;还能使用快捷键 “Control+Command+Q” 锁定屏幕后切换。

359

2025.05.09

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

1564

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

716

2023.06.29

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

300

2023.06.30

linux修改文件名
linux修改文件名

本专题为大家提供linux修改文件名相关的文章,这些文章可以帮助用户快速轻松地完成文件名的修改工作,大家可以免费体验。

800

2023.07.05

linux系统安装教程
linux系统安装教程

linux系统是一种可以免费使用,自由传播,多用户、多任务、多线程、多CPU的操作系统。本专题提供linux系统安装教程相关的文章,大家可以免费体验。

588

2023.07.06

linux查看文件夹大小
linux查看文件夹大小

Linux是一种自由和开放源码的类Unix操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。linux怎么查看文件夹大小呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

570

2023.07.20

linux查看ip命令
linux查看ip命令

本专题为大家提供linux查看ip命令相关文章内容,感兴趣的朋友可以免费下载体验试试。

314

2023.07.20

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 10.6万人学习

Git 教程
Git 教程

共21课时 | 4.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号