os.path.exists()仅判断路径存在性而不区分文件或目录类型,需配合os.path.isfile()或os.path.isdir()做类型校验;pathlib.Path.exists()行为相同但要求Python 3.4+;频繁检查应优先用exists()而非try/except或os.access()。

os.path.exists() 会把文件和目录当成一回事
它只回答“这个路径有没有”,不区分类型。比如 os.path.exists("config") 在当前目录下既有 config 文件又有 config 目录时,都会返回 True;但你真正想读取配置内容时,后者会导致 IsADirectoryError。
所以别单独依赖它做业务判断:
- 要确认是普通文件 → 用
os.path.isfile() - 要确认是目录 → 用
os.path.isdir() - 只关心“路径存在”(比如后续要
os.makedirs(..., exist_ok=True))→os.path.exists()才合适
pathlib.Path.exists() 看起来简洁,但注意 Python 版本
pathlib 是 Python 3.4+ 内置模块,如果你的环境是 Python 2.7 或旧版 3.x,得先装 pathlib2 并用 from pathlib2 import Path。
它的行为和 os.path.exists() 一致:只判存在,不判类型。常见误用是写成:
立即学习“Python免费学习笔记(深入)”;
from pathlib import Path
p = Path("data")
if p.exists(): # ✅ 存在(可能是文件或目录)
p.read_text() # ❌ 如果 p 是目录,这里直接炸
正确姿势是补上类型检查:
-
p.is_file()→ 再读取 -
p.is_dir()→ 再遍历或创建子路径
为什么不用 try/except open() 直接试?
很多人图省事,直接写:
try:
with open("settings.json") as f:
data = json.load(f)
except FileNotFoundError:
data = {}
这在逻辑上没问题,但有隐藏成本:
- 频繁调用(比如循环里检查上百个路径)时,I/O 开销比纯元数据检查大得多
- 无法区分“不存在”和“没权限”——
PermissionError和FileNotFoundError都得单独捕获 - 如果只是“存在就跳过”,用
exists()更轻量;只有“存在才打开”这种场景,才值得用 try 块
os.access() 不是万能的,尤其在 Windows 上
os.access(path, os.R_OK) 看起来很准,但它依赖操作系统级权限检查,在 Windows 下常返回 True 即使实际读不了(比如 NTFS 权限和共享权限不一致),而在 Linux/macOS 下又可能因 umask 或挂载选项误判。
更可靠的做法是:
- 先用
os.path.isfile()或Path.is_file()确认类型 - 再用
try/except实际打开一次(仅关键路径) - 避免对每个路径都调用
os.access(),它不是原子操作,检查完瞬间权限可能已变
实际项目里最容易被忽略的点:路径是否为符号链接。所有上述方法默认跟随软链,如果你需要区分“链接存在”和“链接目标存在”,得加 follow_symlinks=False 参数(os.stat() 支持,pathlib 的 exists() 不支持)。


















