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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 04:57:03