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

Python循环创建带可变参数的调度时参数传递异常问题

问题描述

下述脚本试图在两个指定时间配置调度任务,为每次运行传递独立参数,预期输出为1和2,但实际输出均为2,仅传递了最后一个变量。

import schedule, threading, time


def run_script(n):
    # Check this output
    print(n)

def run_threaded(job_func):
    job_thread = threading.Thread(target=job_func)
    job_thread.start()


times = ["13:56", "13:56"]

for n,row in enumerate(times, 1):
    schedule.every().day.at(row).do(run_threaded, lambda: run_script(n))


while True:
    schedule.run_pending()
    time.sleep(1)

若手动添加调度(不使用循环):

schedule.every().day.at("18:56").do(run_threaded, lambda: run_script(1))
schedule.every().day.at("18:56").do(run_threaded, lambda: run_script(2))

该方式可正常运行,但通过循环生成时结果不符,请问原因是什么?如何解决?

问题原因

这是Python中闭包的延迟绑定导致的问题。循环里的lambda并没有在定义时就捕获当前的n值,而是在实际被调用时才去查找n的当前值。当调度任务触发时,循环已经执行完毕,n的最终值是2,所以两个lambda都会使用这个最终值,导致输出都是2。

解决方法

有三种常见的解决方式:

1. 使用默认参数捕获当前值

在定义lambda时,通过默认参数的方式把当前的n值绑定进去,这样lambda在定义时就会保存当前的n值,而不是等到调用时再查找:

for n,row in enumerate(times, 1):
    schedule.every().day.at(row).do(run_threaded, lambda n=n: run_script(n))

2. 使用functools.partial固定参数

借助functools.partial来创建一个固定了参数的函数,避免闭包的延迟绑定问题:

from functools import partial

# ... 其他代码不变 ...

for n,row in enumerate(times, 1):
    schedule.every().day.at(row).do(run_threaded, partial(run_script, n))

3. 用嵌套函数捕获变量

创建一个嵌套函数,让它在每次循环时捕获当前的n值,返回对应的lambda:

# ... 其他代码不变 ...

for n,row in enumerate(times, 1):
    def get_job_func(current_n):
        return lambda: run_script(current_n)
    schedule.every().day.at(row).do(run_threaded, get_job_func(n))

内容的提问来源于stack exchange,提问作者Roelof Coertze

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:50:21