最简方案是os.makedirs(path, exist_ok=true),python 3.2+原生支持原子性创建,避免竞争条件;旧版本需捕获errno.eexist;pathlib.path(path).mkdir(parents=true, exist_ok=true)更现代但勿忘parents=true。

用 os.makedirs() 配 exist_ok=True 是最简方案
Python 3.2+ 中,os.makedirs() 原生支持原子性创建——即“存在也不报错”,直接绕过竞争条件和重复判断。关键就一个参数:exist_ok=True。它让函数在目录已存在时静默成功,而不是抛出 OSError: [Errno 17] File exists。
常见错误是漏掉这个参数,或在旧版本 Python(如 2.7)上强行使用,结果报 TypeError: makedirs() got an unexpected keyword argument 'exist_ok'。
- 必须确保 Python ≥ 3.2;低于此版本需降级处理(见下一条)
-
exist_ok=True不影响权限检查:如果路径存在但不可写,后续写文件仍会失败,这反而是正确行为 - 不要手动先调
os.path.exists()再调os.makedirs()—— 这会引入竞争条件(中间可能被其他进程删/建)
Python 2.7 或早期 3.x 怎么兼容?
老环境没法用 exist_ok,就得捕获特定错误码。核心逻辑是:只忽略“目录已存在”这一种错误,其他如权限不足、磁盘满、路径含非法字符等,必须暴露出来。
错误示范是裸写 except OSError: 然后 pass —— 这会把 PermissionError 或 IOError 全吞掉,导致问题难以定位。
- 正确做法:导入
errno,检查e.errno == errno.EEXIST - 注意 Windows 下还可能触发
errno.EACCES(访问被拒绝),不能一并忽略 - 示例片段:
import os import errno try: os.makedirs(path) except OSError as e: if e.errno != errno.EEXIST: raise
pathlib.Path().mkdir() 更现代,但要注意 parents 参数
Python 3.4+ 引入的 pathlib 提供了更面向对象的路径操作。创建嵌套目录用 Path(dir_path).mkdir(parents=True, exist_ok=True) 即可。
容易踩的坑是忘记设 parents=True:若父目录不存在,不加该参数会直接报 FileNotFoundError,哪怕 exist_ok=True 也救不了。
-
parents=False(默认):只建最后一级,上级必须已存在 -
parents=True:递归建所有缺失的父级,等价于os.makedirs(..., parents=True) - 路径对象本身不校验权限,创建失败时抛出的异常类型与
os.makedirs()一致(如PermissionError)
权限异常发生时,别急着加 sudo,先确认三件事
真正卡住的往往不是代码写法,而是运行时环境。遇到 PermissionError,90% 情况下问题不在 os.makedirs() 调用本身。
- 检查目标路径的**父目录是否可写**:Linux/macOS 下,创建子目录需要父目录有
w权限;Windows 下看 ACL 是否允许“创建文件/文件夹” - 确认当前用户对路径所在**文件系统是否有写权限**:比如挂载为
ro(只读)的 NFS 或 Docker volume - 留意路径中是否存在**符号链接**:若某级是软链且指向不可写位置,
os.makedirs()会失败,且错误信息不直观
复杂点在于:这些权限问题不会在 os.makedirs() 调用前暴露,只有真正执行时才浮现。所以调试时别只盯着那一行代码,得顺藤摸瓜查路径所有权和挂载属性。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











