如何正确向 threading.Timer 的回调函数传递参数

1次阅读

如何正确向 threading.Timer 的回调函数传递参数

当使用 pythonThreading.timer 定时执行函数时,若目标函数需要接收参数(如 `warntime(i)`),必须通过 `args` 或 `kwargs` 显式传入;直接写 `timer(20, warntime)` 会导致 typeerror,因 timer 默认不提供任何参数。

线程定时任务中,threading.Timer 是一个常用工具,用于延迟执行某个函数。但它的构造签名是:

Timer(interval, function, args=None, kwargs=None)

其中:

  • interval:延迟秒数(Float);
  • function:函数对象本身(不带括号,未调用);
  • args:元组或列表,用于按位置传参(如 (0,) 或 [0]);
  • kwargs:字典,用于按关键字传参(如 {‘i’: 0})。

你原始代码的问题在于:

t = Timer(20, warnTime)  # ❌ 错误:warnTime 被期待接收参数 i,但 Timer 没给

此时 Timer 在 20 秒后调用 warnTime()(无参数),而函数定义为 def warnTime(i):,因此抛出 TypeError: warnTime() missing 1 required positional argument: ‘i’。

✅ 正确做法是显式传入参数:

from threading import Timer  def warnTime(i):     i += 1     print(f"Warning time reached: i = {i}")  # ✅ 传入初始值 0 作为位置参数 t = Timer(20, warnTime, args=[0]) t.start()

? 提示:args 接受序列类型(推荐 list 或 tuple),单个参数时务必写成 [0] 或 (0,),而非 args=0(会报错)。

如需传多个参数,例如 def warnTime(i, msg),可写为:

t = Timer(20, warnTime, args=[5, "Overdue!"])

或使用关键字参数(更清晰、可读性更强):

def warnTime(i=0, msg="Alert"):     i += 1     print(f"{msg}: i = {i}")  t = Timer(20, warnTime, kwargs={"i": 0, "msg": "Timeout"})

⚠️ 注意事项:

  • Timer 只执行一次;如需周期性执行,请自行在函数内递归启动新 Timer,或改用 threading.Thread + time.sleep() 循环
  • 若函数中修改的是不可变对象(如 int, str),参数传递为值传递,原变量不会被外部影响(本例中 i += 1 仅作用于函数局部);
  • 确保 args/kwargs 中的数据在线程执行时仍有效(避免引用已销毁的对象)。

总结:向 Timer 回调函数传参不是“调用函数”,而是配置其未来调用的方式——关键在于正确使用 args 或 kwargs 参数,而非在构造时加括号调用函数。

text=ZqhQzanResources