最稳妥做法是用os.path.dirname()提取目录再调用os.makedirs(..., exist_ok=True);pathlib.Path.mkdir(parents=True, exist_ok=True)更简洁;封装安全写入函数可避免重复操作。

用 os.makedirs() 配合 os.path.dirname() 提前建目录
Python 的 open() 本身不创建父目录,直接写入会抛出 FileNotFoundError。必须手动确保路径存在。最稳妥的做法是先提取目标文件的目录部分,再递归创建——os.makedirs() 的 exist_ok=True 参数能避免已存在时报错。
常见错误是只对完整路径调用 os.makedirs(path),结果把文件名也当成目录建了(比如 os.makedirs("a/b/c.txt") 会尝试创建名为 c.txt 的目录,失败)。
实操建议:
- 用
os.path.dirname("a/b/c.txt")拿到"a/b",再传给os.makedirs(..., exist_ok=True) - Windows 和 Linux 路径分隔符不同,但
os.path系列函数自动适配,不用硬写"\"或"/" - 如果路径是相对路径(如
"data/log/app.log"),os.makedirs()会相对于当前工作目录创建,注意 cwd 是否符合预期
更简洁:用 pathlib.Path.mkdir()(推荐 Python 3.4+)
pathlib 是现代 Python 处理路径的首选。它的 mkdir() 方法默认不递归,但加 parents=True 就等价于 os.makedirs();再配合 exist_ok=True,一行就能搞定目录准备。
立即学习“Python免费学习笔记(深入)”;
使用场景:适合新项目或已用 pathlib 管理路径的代码,语义清晰、链式调用自然。
示例:
from pathlib import Path
p = Path("output/reports/2024/q3/data.csv")
p.parent.mkdir(parents=True, exist_ok=True)
with p.open("w") as f:
f.write("hello")
注意:p.parent 是关键,不能写成 p.mkdir(...) —— 否则又试图把文件当目录建。
封装成可复用的写入函数(避免重复写 mkdir)
每次写文件都手动 mkdir 很啰嗦,尤其在批量导出场景下。可以封装一个安全写入函数,内部统一处理路径检查。
要点:
- 接受
path(字符串或Path对象)、content、mode等参数 - 内部统一用
Path(path).parent.mkdir(parents=True, exist_ok=True) - 支持文本和 bytes 写入(根据
mode自动判断是否需要encoding) - 不吞异常:如果
mkdir失败(如权限不足),应让错误暴露,而不是静默忽略
为什么不用 shutil.os.makedirs(..., exist_ok=True)?
有人会查到 shutil 模块也有 os 属性,误以为 shutil.os.makedirs() 是独立实现。其实它只是对 os 模块的引用,和直接导入 os 完全等价。这种写法纯属冗余,还可能误导别人以为有额外功能。
真正要注意的是权限问题:即使加了 exist_ok=True,如果父目录存在但不可写(比如 /var/log 下无权限),open() 仍会报 PermissionError。这时候 mkdir 成功了,但写入失败——这是两个独立环节,得分别处理。
路径中含 "~"(用户主目录符号)时,os.path.dirname() 不会自动展开,需先用 os.path.expanduser();pathlib.Path 同样需要显式调用 .expanduser()。


















