未找到文件时无法抛出FileNotFoundError问题求助
问题解决:文件未找到时正确抛出
FileNotFoundError及写法对比 问题根源分析
- 第一种写法:
try-except仅捕获open操作的异常,但未找到文件时根本不会执行open,循环结束后函数默认返回None,不会触发异常分支。 - 第二种写法:
else分支永远无法执行——前面已经通过if not file.endswith(file_name): continue跳过了非目标文件,剩下的必然满足匹配条件,遍历结束后无异常抛出。
正确实现逻辑
核心:遍历完所有目录和文件后,若未找到目标文件,主动抛出FileNotFoundError。
优化写法一(保留异常捕获,处理文件读取/解析错误)
import os import json def get_file_data(src_path, file_name): for root, _, files in os.walk(src_path): for file in files: if file.endswith(file_name): file_path = os.path.join(root, file) print("File Found: ", file_path) try: with open(file_path, "r+", encoding="utf-8") as data_file: return json.load(data_file) except (FileNotFoundError, json.JSONDecodeError) as err: # 捕获文件读取或JSON解析时的异常,抛出更明确的错误信息 raise RuntimeError(f"Failed to process file {file_path}: {err}") from err # 遍历结束仍未找到,主动抛出目标异常 raise FileNotFoundError(f"{file_name} doesn't exist in {src_path} or its subdirectories")
优化写法二(简化逻辑,聚焦核心功能)
import os import json def get_file_data(src_path, file_name): for root, _, files in os.walk(src_path): for file in files: if file.endswith(file_name): file_path = os.path.join(root, file) print("File Found: ", file_path) with open(file_path, "r+", encoding="utf-8") as data_file: return json.load(data_file) # 遍历结束未找到,主动抛出异常 raise FileNotFoundError(f"{file_name} doesn't exist in {src_path} or its subdirectories")
写法优劣对比
写法二更推荐:
- 去掉了冗余的分支判断(原写法中重复判断
file.endswith(file_name)),逻辑更简洁清晰。 os.walk本身不会因目标文件不存在抛出异常,无需额外包裹try-except,仅在遍历结束后主动抛出即可。
- 去掉了冗余的分支判断(原写法中重复判断
写法一的适用场景:
- 当需要处理文件存在但无法读取、JSON格式错误等异常时,保留内部
try-except并重新抛出更具体的异常,方便调用方排查问题。
- 当需要处理文件存在但无法读取、JSON格式错误等异常时,保留内部
测试用例适配
你的pytest测试用例可以直接使用优化后的函数,遍历结束后主动抛出的FileNotFoundError完全符合测试预期。
额外建议
- 若要校验源路径
src_path本身是否存在,可在函数开头添加:if not os.path.exists(src_path): raise FileNotFoundError(f"Source path {src_path} doesn't exist") - 若需要精确匹配文件名而非后缀匹配,将
file.endswith(file_name)改为file == file_name即可。
内容的提问来源于stack exchange,提问作者Muhammad Shaheer Munir
相关产品推荐
相关产品推荐

