Python使用threading.Timer报NoneType不可调用错误如何解决
问题原因
你在实例化threading.Timer时直接执行了self.readMessages(self.queue, self.client),该方法没有显式返回值时默认返回None,Timer实际接收到的执行目标是None,因此30秒后触发调度时会抛出TypeError: 'NoneType' object is not callable异常。你感知到的"第一次运行正常",实际是实例化Timer时同步执行了readMessages,并非Timer调度触发的执行。
单次Timer修复方法
如果仅需要执行一次延迟调用,直接将函数参数通过Timer的args参数传递即可,不要当场调用目标方法:
def start(self): sync_thread = threading.Timer(30, self.readMessages, args=(self.queue, self.client)) sync_thread.start()
周期性拉取的实现方案
原生threading.Timer是一次性调度工具,要实现每隔指定时间执行一次的需求,可采用以下两种方案:
方案1:循环创建Timer实现调度
每次任务执行完成后新建下一次的Timer实例,同时增加运行状态控制方便优雅停止:
import threading class YourClass: # __init__等原有逻辑保留 def start(self): self._running = True self._schedule_next() def _schedule_next(self): if self._running: # 创建30秒后执行的Timer self.timer = threading.Timer(30, self._run_task) self.timer.start() def _run_task(self): try: self.readMessages(self.queue, self.client) finally: # 无论任务是否执行异常,都调度下一次 self._schedule_next() def stop(self): self._running = False if hasattr(self, 'timer'): self.timer.cancel()
方案2:独立守护线程+sleep循环实现
逻辑更简单,适合轻量定时场景,主线程退出时守护线程会自动销毁:
import threading import time class YourClass: # __init__等原有逻辑保留 def start(self): self._running = True # 设为守护线程,随主线程退出自动终止 self.sync_thread = threading.Thread(target=self._loop_task, daemon=True) self.sync_thread.start() def _loop_task(self): while self._running: try: self.readMessages(self.queue, self.client) except Exception as e: # 按需添加异常处理逻辑,避免单次任务错误终止整个循环 print(f"拉取任务执行异常: {e}") # 任务执行完成后休眠30秒 time.sleep(30) def stop(self): self._running = False # 等待线程安全退出,可选 self.sync_thread.join(timeout=35)
注意事项
- 如果需要严格每隔30秒执行一次(不包含任务本身执行耗时),可在任务执行前记录时间戳,执行完成后计算剩余休眠时间再调用sleep
- 建议对
readMessages添加异常捕获,避免单次任务报错导致整个定时逻辑终止 - 应用退出时主动调用
stop方法,避免线程残留
内容的提问来源于stack exchange,提问作者anho
相关产品推荐
相关产品推荐

