You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何在带计数器的for循环内调度API调用

实现逻辑问题排查

你当前写的暂停逻辑有3个致命问题,运行后完全达不到预期效果:

  • 计数统计不准确:count累加放在了返回值非空的判断分支里,API返回None(比如请求失败、目标数据为空)的场景不会被计数,实际调用次数达到450次的限流阈值时,程序不会触发暂停。
  • schedule库使用逻辑错误:
    1. 触发阈值时你注册了每小时递归调用master_function()的定时任务,之后进入死循环跑调度,会导致整个函数从头开始重复执行,之前已经拉取的数据、计数状态全部重置,最终出现重复拉取、内存溢出、无限递归的问题。
    2. 这个死循环没有退出条件,就算1小时后任务执行完成,程序也永远跳不出循环,不会继续处理剩余的测试项。
  • 计数器没有重置逻辑:就算勉强实现了暂停,恢复执行后count的值仍然是450,下一次循环会立刻再次触发暂停,程序会卡在反复等待的状态无法继续。
正确实现方式

不需要引入schedule做定时任务,直接用标准库的time.sleep()就能满足需求,核心调整点:

  1. 把计数器累加移动到API调用语句之后,只要发起了API请求就计数,完全匹配限流统计规则。
  2. 触发450次阈值时直接休眠3600秒(即1小时),休眠结束后把计数器重置为0,继续循环处理后续数据即可。
  3. 删除递归调用主函数、死循环跑调度的错误逻辑。
  4. 把原代码里的变量名id改成test_id,避免覆盖Python内置的id()函数引发异常。

修正后的完整可运行代码如下:

import time
import pandas as pd
# 其余原有依赖导入保持不变

def master_function():
    test_data = sev_one_api_calls.get_all_catchpoint_tests()
    flat_getAll = pd.DataFrame([flatten_json(test_data[key]) for key in test_data])
    
    call_count = 0
    concat_data = pd.DataFrame()
    for test_name, test_details in test_data.items():
        test_id = test_details.get('id')
        print(test_name, test_id)
        
        # 发起API请求后直接计数,不管返回结果是否为空
        test_detailed_data = sev_one_api_calls.get_catchpoint_test_detail(test_id)
        call_count += 1

        if test_detailed_data is not None:
            flat_detailed_data = json_to_dataframe(test_detailed_data)
            concat_data = pd.concat([concat_data, flat_detailed_data], ignore_index=True)

        # 达到阈值时暂停1小时,重置计数器
        if call_count >= 450:
            print(f"累计API调用达到450次,暂停1小时,暂停开始时间:{time.ctime()}")
            time.sleep(3600)
            call_count = 0
            print(f"暂停结束,恢复执行,恢复时间:{time.ctime()}")

    # 后续数据合并、导出逻辑保持原有逻辑不变
    combined = pd.merge(flat_getAll, concat_data, on='id', how='outer', left_index=True,
                      right_index=True, suffixes=('', '_remove'))
    combined.drop([i for i in combined.columns if 'remove' in i],
                axis=1, inplace=True)

    df = combined.groupby('id', as_index=False).first()
    df.to_csv('../../data/COMBO.csv', index=False)
可选优化点
  • 循环内反复用pd.concat拼接DataFrame的效率极低,数据量大时运行速度会非常慢,可以先把所有拉取到的明细数据存在Python列表里,等整个循环结束后一次性转成DataFrame,性能会有明显提升。
  • 建议给API调用加try-except异常捕获和有限次重试逻辑,避免单次网络波动、请求失败导致整个任务中断。
  • 如果对接的API限流规则是自然小时窗口(比如每自然小时最多允许450次请求,而非每打满450次硬等1小时),可以记录窗口内第一次请求的时间戳,到阈值时计算当前窗口剩余等待时间即可,不需要每次都等满1小时,能大幅缩短整体任务耗时。

内容的提问来源于stack exchange,提问作者Rebekah Lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 09:39:57