用 Python 写一个带超时和重试的 JSON 文件读取工具
【摘要】 用 Python 写一个带重试和总超时预算的 JSON 文件读取工具:失败时按间隔重试,超过预算抛出最后一次错误,不吞异常,附可直接运行的示例。
读本地 JSON 配置时,最常见的失败不是代码写错,而是文件还没写好、正在被另一个进程写入,或者路径暂时不存在。直接 json.load 一次就报错,程序就退出了。本文写一个小工具:读取失败时按间隔重试,并在总超时内放弃,把最后一次错误原样抛出来,调用方可以据此决定是报警还是用默认值。
思路
- 只捕获真正属于“暂时读不到”的错误:文件不存在、JSON 解析失败、一般的读写错误。
- 每次失败后等待一小段时间再试,而不是立刻死循环重试。
- 用总超时控制重试预算:超过预算就停止,并抛出最后一次错误,不吞掉异常。
这里的“超时”指的是重试总预算,不是操作系统层面的文件锁超时,这一点在调用时要说清楚。
代码
import json
import time
from pathlib import Path
def read_json_with_retry(path, attempts=3, interval=0.5, timeout=5.0):
"""带重试和总超时预算的 JSON 文件读取工具。"""
start = time.monotonic()
last_error = None
for _ in range(attempts):
try:
text = Path(path).read_text(encoding="utf-8")
return json.loads(text)
except (FileNotFoundError, json.JSONDecodeError, OSError) as exc:
last_error = exc
if time.monotonic() - start >= timeout:
break
time.sleep(interval)
raise last_error
if __name__ == "__main__":
data = read_json_with_retry("config.json")
print(data)
使用示例
先准备一个 config.json:
{"name": "demo", "retries": 3}
再运行上面的脚本,输出为:
{'name': 'demo', 'retries': 3}
两个注意点
- 如果文件内容本身就是非法 JSON,重试不会把它变合法,工具最终仍会抛出 JSONDecodeError,这正是我们想要的:不要把格式错误伪装成成功。
- 如果业务上确实需要“读不到就用默认值”,请在调用处显式处理,例如用 try/except FileNotFoundError 包裹调用,而不是让读取工具悄悄返回一个假配置。
这个工具只有几十行,没有外部依赖,适合放在配置加载、本地缓存读取这类小场景里。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)