Python 如何不抛异常地检查文件是否存在
os.path.exists() 或 Path.is_file() 可检查路径,is_file 区分普通文件和目录。返回 False 也可能意味着不可访问;检查后读取仍需处理竞态和权限错误。
一句话回答:对合法路径通常返回 True/False:Python 3.14 的 pathlib 将操作系统 OSError 抑制为 False,旧版部分错误仍可能抛出:os.path.exists(路径)(文件或目录存在都返回 True),或 Path(路径).is_file()(仅当是文件时返回 True,推荐)。要区分目录用 is_dir()。
两种写法
os.path(传统):
from os.path import exists
if exists('/data/some_file.txt'):
print('存在')
pathlib(推荐,Python 3.4+):
from pathlib import Path
path = Path('/data/some_file.txt')
path.exists() # 文件或目录存在 → True
path.is_file() # 是文件 → True(目录会返回 False)
path.is_dir() # 是目录 → True
is_file() 更严谨:exists() 对目录也返回 True,如果你的逻辑是"读取文件",目录存在会导致后续的 open() 抛 IsADirectoryError。
竞态问题:检查≠可用
"先检查再打开"之间文件可能被别的进程删掉(TOCTOU 竞态):
# 看似安全,仍有缝隙
if path.is_file():
data = path.read_text() # 这一刻文件可能已不存在
对"要读文件"的场景,更 Pythonic 的做法是直接操作并捕获异常(EAFP):
try:
data = path.read_text()
except FileNotFoundError:
data = None
# PermissionError、IsADirectoryError 等应按业务处理,不要一概吞掉
何时用哪种:只是想知道"存不存在"(如展示下载状态)→ is_file();紧接着就要读写 → try-except 更可靠。防止覆盖应使用独占创建模式 open(path, "x") 并处理 FileExistsError,而不是先 exists 再写;False 也可能表示无权限,不能一律解释为不存在。
常见问题(FAQ)
Q:路径里有 ~(家目录)为什么返回 False?
A:exists/is_file 不会自动展开 ~。先 Path('~/file.txt').expanduser() 再判断。
Q:符号链接断了,exists() 返回什么?
A:返回 False(exists 跟随链接,目标不存在即为 False)。要判断"链接本身存在"用 Path.is_symlink() 或 os.path.lexists()。
Q:Windows 路径怎么写?
A:pathlib 是跨平台的:Path('C:/data/file.txt') 或用原始字符串 Path(r'C:\data\file.txt')。避免在普通字符串里写单反斜杠路径,\U、\n 会被当转义符。
核查依据
本文依据官方文档核对,示例未在实际业务环境运行;上线前请按部署版本、权限与数据范围验证。