Python pathlib.Path.mkdir 的 parent_mode 怎么影响中间目录
来源:17golang原创
时间:2026-09-09 06:45:22 243浏览 收藏
如果你在 Python 3.15 中用 pathlib.Path.mkdir(parents=True) 创建 cache/service/v1,又希望叶目录和中间目录采用不同权限,答案是:把叶目录权限交给 mode,把递归创建的中间目录权限交给新增的 parent_mode。两者都会再经过进程的 umask,而且 parent_mode 只有在 parents=True 时才有意义。
mode控制本次目标叶目录,parent_mode控制缺失的中间目录。- 已存在的父目录不会被
mkdir重新改权限,exist_ok=True也不会改变它。 - Python 3.14 及更早版本不认识
parent_mode,需要先创建,再用os.chmod调整。
Python 3.15 的变化到底改了什么
过去,Path.mkdir(mode=..., parents=True) 可以递归补齐缺失目录,但 mode 主要对应最终目标目录;中间目录按系统默认创建权限处理。Python 3.15 给签名增加了关键字参数 parent_mode,让调用者明确表达“中间目录要用什么模式”。
这里的“中间目录”是目标路径最后一段之前缺失的那些目录。例如目标是 cache/service/v1,如果三个目录都不存在,v1 是叶目录,cache 和 service 是中间目录。parents=True 负责允许递归创建,parent_mode 只负责补齐中间层。

mode、parent_mode 和 umask 怎么分工
可以先记住下面这张边界表。它比“把两个参数都设成同一个八进制值”更能避免误解:
| 对象 | 参数或因素 | 作用 |
|---|---|---|
| 目标叶目录 | mode | 设置最终目录的请求模式 |
| 缺失中间目录 | parent_mode | 设置递归补齐的父级目录模式 |
| 所有新建目录 | umask | 参与计算最终实际权限 |
| 已存在目录 | exist_ok | 影响报错策略,不负责改权限 |
最小写法如下。0o750 只给叶目录使用,0o710 给中间目录使用;这段代码不需要手动拆分路径。
from pathlib import Path
target = Path("cache/service/v1")
# 叶目录使用 mode,中间目录使用 parent_mode。
target.mkdir(
mode=0o750,
parents=True,
exist_ok=True,
parent_mode=0o710,
)
注意两个边界:第一,父目录已经存在时,parent_mode 不会追溯修改它;第二,权限位还会受到 umask 影响,所以代码中的模式是请求值,不一定等于 stat().st_mode 读到的最终值。
为旧版本保留兼容写法
如果项目还支持 Python 3.14 或更早版本,不能无条件传入 parent_mode,否则旧解释器会因为不接受这个关键字而失败。兼容思路是先递归创建,再只调整这次确实缺失的父级目录;不要顺手修改整个已有目录树。
import os
from pathlib import Path
def mkdir_with_parent_mode(path: Path, leaf_mode: int, parent_mode: int) -> None:
# 记录创建前不存在的祖先,避免改动原本已有的目录权限。
missing = []
current = path.parent
while not current.exists():
missing.append(current)
current = current.parent
# 旧版本只使用 parents 和叶目录的 mode。
path.mkdir(mode=leaf_mode, parents=True, exist_ok=True)
for directory in missing:
# 从外层到内层调整,保证每个新建父目录都被覆盖。
os.chmod(directory, parent_mode)
这个封装的取舍很明确:Python 3.15 可以直接使用新参数;旧版本则多一步权限调整。若目录创建发生并发竞争,权限修改仍应放在受控部署流程中,并结合进程的 umask 与平台权限模型测试。

最小验证清单:别只看调用没有报错
验证时使用一个全新的临时根目录,分别检查叶目录和每一级中间目录的模式。不要只测目标目录,因为那只能证明 mode 起作用,无法证明 parent_mode 真的覆盖了递归层。
- 确认运行解释器版本;只有 Python 3.15 才直接测试
parent_mode。 - 让目标路径的父级全部不存在,再调用
mkdir(parents=True)。 - 用
stat().st_mode & 0o777读取各级目录,并把当前umask纳入预期。 - 再次调用并确认
exist_ok=True不会把已有父目录改成新的parent_mode。
如果部署环境必须支持多个 Python 小版本,更稳妥的做法是把兼容封装集中在一个文件里,并在 CI 矩阵中覆盖“全新目录”和“部分目录已存在”两种状态。这样升级到 3.15 时,只需替换实现,不必让业务代码到处判断版本。
常见问题
parent_mode 能修改已经存在的父目录吗?
不能。它只参与新建的中间目录;已有目录的权限需要显式调用权限 API,并应评估是否会影响其他进程。
把 mode 和 parent_mode 设成一样是不是就没有区别?
结果可能相同,但职责仍不同:前者描述叶目录,后者描述递归创建的中间目录。保留分开设置的写法,后续调整权限策略时更清楚。
旧版本能不能用位置参数传 parent_mode?
不能。新参数是关键字参数,而且旧版本连这个参数名都不支持;应采用先创建再调整父目录的兼容封装。
-
339 收藏
-
388 收藏
-
253 收藏
-
182 收藏
-
374 收藏
-
260 收藏
-
217 收藏
-
文章 · python教程 | 3小时前 | python · risc-v · Python 3.15 · riscv64 · 原生扩展 · Python打包 · RISC-V wheel Python 3.15 riscv64 Python扩展493 收藏
-
388 收藏
-
236 收藏
-
495 收藏
-
125 收藏
-
文章 · python教程 | 9小时前 | JSON · Python教程 · 异常排查 · 数据解析 · Python json.loads JSONDecodeError lineno colno pos JSON排错326 收藏
-
371 收藏
-
181 收藏
-
348 收藏
-
256 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习