APScheduler使用date触发器时函数立即执行问题求助
问题原因&解决方案
你遇到的问题很典型——你在添加任务时直接执行了函数,而不是把函数作为待执行的任务传给调度器。
看你代码里这一行:
scheduler.add_job(two_minute_scrape(url, track, 5), 'date', scheduled_time)
这里two_minute_scrape(url, track, 5)是直接调用函数,所以它会立刻执行,调度器收到的其实是这个函数的返回值(如果函数没有return,就是None),而不是一个待执行的任务。
正确的两种写法
方法1:使用APScheduler的args参数(推荐)
直接传递函数对象(不带括号),然后用args参数把函数需要的参数传进去,同时指定run_date来设置执行时间:
for mtp, url, track in zip(mtp_num_final, url_list, race_list): scheduled_time = datetime.now() + relativedelta(minutes=mtp - 2) # 修正原代码里`minutes =+`的笔误,应为`minutes=mtp-2` print(scheduled_time.strftime('%m-%d-%Y %I:%M%p')) scheduler.add_job(two_minute_scrape, 'date', run_date=scheduled_time, args=[url, track, 5])
这种方式是APScheduler的标准用法,不会有变量绑定的陷阱,更可靠。
方法2:用lambda表达式包裹函数调用
如果更喜欢用lambda,需要注意循环变量的后期绑定问题,最好把参数作为默认值传入lambda:
for mtp, url, track in zip(mtp_num_final, url_list, race_list): scheduled_time = datetime.now() + relativedelta(minutes=mtp - 2) print(scheduled_time.strftime('%m-%d-%Y %I:%M%p')) scheduler.add_job(lambda u=url, t=track: two_minute_scrape(u, t, 5), 'date', run_date=scheduled_time)
如果不设置默认参数,所有lambda可能会捕获循环最后一次的url和track值,导致执行时参数错误,所以一定要加默认值。
内容的提问来源于stack exchange,提问作者ike
相关产品推荐
相关产品推荐

