本文介绍如何在 python for 循环中对失败操作(如股票数据下载)进行自动重试,而非跳过或中断流程;核心方案是嵌套 while/for 循环配合异常捕获与 break/else 逻辑,确保每个 ticker 至少成功获取一次有效数据。
本文介绍如何在 python for 循环中对失败操作(如股票数据下载)进行自动重试,而非跳过或中断流程;核心方案是嵌套 while/for 循环配合异常捕获与 break/else 逻辑,确保每个 ticker 至少成功获取一次有效数据。
在批量处理外部 API 数据(例如使用 yfinance 下载股票历史行情)时,网络波动、服务限流或临时无数据等情况极易导致单次请求返回空 DataFrame 或抛出异常。若仅用 continue 跳过失败项,将造成后续分析阶段缺失关键资产数据;而手动重跑又违背自动化初衷。真正健壮的解决方案不是“跳过”,而是“重试”——即对当前迭代项反复尝试,直至成功或达到最大重试次数。
最简洁、Pythonic 的实现方式是在 for 循环内部嵌套一层有限次 retry 循环,并利用 try...except 捕获异常,配合 break 提前退出重试、else 子句识别彻底失败:
import yfinance as yf
trade_sym = ["AAPL", "XOM", "TSLA", "GOOGL"]
wdir = "./data/"
retry_limit = 3
for sym in trade_sym:
success = False
for attempt in range(1, retry_limit + 1):
try:
print(f"[{attempt}/{retry_limit}] Getting {sym} data...")
p_data = yf.download(sym, auto_adjust=True, period="1y")
# 关键校验:确保下载到有效数据(非空且含时间序列)
if not p_data.empty and len(p_data) > 1:
# 数据处理逻辑(例如添加技术指标、清洗列名等)
p_data = p_data[["Open", "High", "Low", "Close", "Volume"]]
# 写入文件
o_file = wdir + sym + ".csv"
p_data.to_csv(o_file)
print(f"✓ Saved {sym} ({len(p_data)} rows)")
success = True
break # 成功则跳出重试循环,进入下一个 ticker
else:
raise ValueError("Download returned empty or insufficient data")
except Exception as e:
print(f"✗ {sym} failed on attempt {attempt}: {type(e).__name__} - {e}")
if not success:
print(f"⚠ Skipping {sym}: all {retry_limit} attempts failed.")✅ 关键设计说明:
- 外层 for sym in trade_sym 保证每个 ticker 必然被处理一次;
- 内层 for attempt in range(...) 提供可控的重试上限,防止无限等待;
- break 仅终止内层循环,外层继续执行下一 symbol;
- if not p_data.empty and ... 是业务级校验,比单纯捕获异常更可靠——因为 yf.download() 可能静默返回空 DataFrame 而不抛异常;
- 使用 success 标志+最终 if not success 分支,可统一记录失败项用于日志审计或后续补采。
⚠️ 注意事项:
立即学习“Python免费学习笔记(深入)”;
- 避免无休止重试:务必设置 retry_limit(通常 3–5 次足够),并加入 time.sleep(1)(尤其对有速率限制的 API);
- 不要滥用 except:(裸异常捕获),应明确捕获 Exception 或具体异常类型(如 yf.YFNetworkError, yf.YFException);
- 若需异步高并发,建议改用 asyncio + aiohttp + yfinance 异步封装,但重试逻辑结构保持一致;
- 生产环境建议集成日志模块(logging)替代 print,便于追踪和告警。
总结而言,Python 并不支持传统 C 风格的“修改 for 循环索引”,但这恰是语言设计的深意:鼓励更清晰、更可控的控制流。通过嵌套 retry 循环,你既实现了“重复当前项”的语义,又保持了代码可读性、可测试性与健壮性——这才是专业数据管道应有的姿态。









