本文要点
先看只缺中间层的情况
再看目标已经存在的情况
要区分这两种情况,可以用 Path.is_dir() 和 Path.is_file() 分别判断,而不是只看 exists()

本文目录
先回答:多级目录要一次建好,两个参数各管一件事
如果你要在练习目录里建一条像 exercise/demo/data/raw 这样的多级路径,中间几层还不存在,直接用 Path.mkdir() 会失败,因为默认只建最后一级。
按 pathlib 文档,mkdir 属于具体路径(concrete path)提供的系统调用方法,用来创建目录。它有两个关键参数:
- parents:设为 True 时,缺失的中间父目录会被一并创建。
- exist_ok:设为 True 时,目标目录已经存在不报错。
这两个参数解决的是两个不同问题。parents 管“中间层缺不缺”,exist_ok 管“目标层在不在”。写脚本时把它们分开想,就不会把“目录已存在”和“父目录缺失”混成一种错误。
本文只在你自己的练习相对路径下创建目录,例如 exercise/ 下面。不要对系统目录、其他程序目录或你不确定归属的路径执行创建操作。下面所有路径和内容都是自建练习示例,不是对真实目录的记录。
parents 解决的是中间层级缺失,不是目标已存在
先看只缺中间层的情况。假设练习目录里还没有 demo 这一层,你想建 exercise/demo/data/raw:
from pathlib import Path
target = Path("exercise/demo/data/raw")
target.mkdir(parents=True)这里 parents=True 的作用是:把 exercise/demo、exercise/demo/data 这些还不存在的父目录一起建出来,最后建出 raw。
如果不写 parents=True,而 exercise/demo 不存在,mkdir 会因为找不到父目录而失败。这不是权限问题,也不是路径写错,而是默认行为只处理最后一段。
一个容易忽略的点:parents 只影响“要不要补建父目录”,它不改变“目标目录已存在时怎么办”。目标已存在这件事由下一个参数处理。
exist_ok 只容忍目录已存在,同名文件仍会报错
再看目标已经存在的情况。假设 exercise/demo/data/raw 这个目录上次已经建过,你再运行一次同样的代码:
from pathlib import Path
target = Path("exercise/demo/data/raw")
target.mkdir(parents=True, exist_ok=True)exist_ok=True 让这次调用在“目标已经是一个目录”时安静通过,不抛异常。这样脚本重复运行不会因为目录已存在而中断。
但要注意它的边界:exist_ok 容忍的是“已存在的目录”。如果 exercise/demo/data/raw 这个位置上是一个同名文件,而不是目录,即使写了 exist_ok=True,mkdir 仍然会报错。因为文件不能当作目录使用,exist_ok 不会把文件替换成目录,也不会删除它。
所以判断顺序可以固定成两步:
1. 先看目标位置上有没有东西。
2. 如果有,判断它是目录还是文件。是目录,exist_ok=True 可以通过;是文件,先停下,换路径或先处理这个文件,不要指望 mkdir 帮你覆盖。
已存在目录和同名文件的区别,用两个检查分开看
要区分这两种情况,可以用 Path.is_dir() 和 Path.is_file() 分别判断,而不是只看 exists()。
exists() 只回答“这个路径上有没有东西”,它不区分是文件还是目录。文档也说明,exists() 在路径指向已存在的文件或目录时返回 True。所以只靠 exists() 无法决定能不能继续建目录。
下面是一段只读检查的示例,不创建也不修改任何东西:
from pathlib import Path
target = Path("exercise/demo/data/raw")
if target.is_dir():
print("已存在,且是目录")
elif target.is_file():
print("已存在,但是文件,不能当目录用")
else:
print("这个位置目前没有东西")这段代码只打印判断结果。你可以先跑它,再决定要不要执行 mkdir。这样做的价值在于:把“建目录”和“检查现状”分开,避免在没看清目标是什么的情况下直接创建。
需要提醒的是,is_dir() 和 is_file() 都是对当前状态的查询,路径不存在时返回 False,不会抛异常。所以两个都为 False,通常说明这个位置还没有东西。
把检查、创建、复核串成一次练习流程
把前面几步连起来,可以形成一条只针对自建练习路径的操作顺序。以下顺序是编辑建议的练习流程,不是对某个真实目录的测试记录。
1. 先确认练习根目录。用 Path("exercise") 作为起点,所有创建都限制在它下面。
2. 检查目标。用 is_dir() 和 is_file() 看 exercise/demo/data/raw 当前是什么状态。
3. 如果是文件,停止。换一个目标名,或先把这个练习文件挪走(在练习目录内操作)。
4. 如果是目录,直接跳过创建。
5. 如果不存在,执行 mkdir(parents=True, exist_ok=True)。
6. 复核。再跑一次第 2 步的检查,确认目标现在是目录。
复核这一步容易被省掉。它的作用是确认创建结果符合预期,而不是假设命令一定成功。复核只读取状态,不改动文件。
创建失败时,先分清是哪一类原因
mkdir 失败时,报错信息里通常能看出方向。可以按下面几类先分:
- 父目录缺失:如果没写 parents=True,而中间层不存在,会失败。处理方式是补上 parents=True,或先手动建父目录。
- 目标已存在且是文件:exist_ok=True 也救不了。处理方式是换目标名,或先处理这个同名文件。
- 目标已存在且是目录:如果没写 exist_ok=True,会失败;补上它即可。
- 路径写成了绝对路径或指向系统位置:这不是本文的适用范围。请把路径改回 exercise/ 下面的相对路径,不要在系统目录上尝试创建。
排查时建议先打印出你实际使用的路径,确认它确实是练习相对路径,而不是手误写成了别的位置。打印路径是只读操作,不会改动文件系统。
适用范围与限制
本文只讨论在自建练习路径下用 Path.mkdir 创建多级目录,以及 parents 和 exist_ok 两个参数的分工。
明确不涉及的内容:
- 不在系统目录、程序安装目录或其他你不确定归属的位置执行创建。
- 不讨论删除目录、递归删除或覆盖文件。
- 不讨论权限设置、符号链接解析和并发创建。
- 不给出任何目录结构规范或命名标准。
关于版本:pathlib 从 Python 3.4 开始提供,Path 是最常用的具体路径类。mkdir 的 parents 和 exist_ok 是它的基础参数。不同 Python 版本在个别方法上有变化,但本文用到的这两个参数属于基础用法。
动手前请把练习文件放在单独目录,例如 exercise/,不要拿重要目录直接试。本文所有路径、文件名和输出描述都是自建练习示例。
观看知识要点视频 18 秒
18秒无旁白要点导览,文字来自已审核正文;完整步骤、条件及参考资料见下方。
参考资料
以下原始资料提供本文依据;请结合日期、适用条件和产品说明查阅。
请结合原始资料的适用条件阅读。
返回文件整理 →