
当使用 python 的 Threading.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 参数,而非在构造时加括号调用函数。