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

Python类通过MQTT回调更新属性后val方法返回0如何修复

Python MQTT类取值异常修复方案

问题原因

核心问题是MQTT客户端的消息回调为异步执行逻辑,和主线程的执行时序不同步:

  1. 实例化Foo类后立刻调用val()方法时,customCallback还未收到MQTT消息触发执行,temp、hum、ppm三个属性仍为初始化时的默认值0,因此val()返回值全为0。
  2. 你看到的10 20 30是后续MQTT消息推送后才触发回调打印的内容,因标准输出缓冲问题,看起来打印顺序和实际执行顺序不一致。

修复方案

首先要确保你已经正确启动了MQTT客户端的后台事件循环,否则回调永远不会触发。以下是完整修复后的代码:

import json
import threading
# 此处保留你原有myMQTTClient的初始化逻辑,不要删除

class Foo(object):
    def __init__(self, temp=0, hum=0, ppm=0):
        self.temp = temp
        self.hum = hum
        self.ppm = ppm
        # 新增事件标志,标记是否已经收到过MQTT消息
        self.data_received = threading.Event()
        myMQTTClient.subscribe("test", 1, self.customCallback)
        # 启动MQTT消息处理后台循环,漏写这行回调永远不会触发
        myMQTTClient.loop_start()

    def customCallback(self, client, userdata, message):
        data = json.loads((message.payload).decode("utf-8"))
        self.temp = data["Temperature"]
        self.hum = data["Humidity"]
        self.ppm = data["Particulate count"]
        # 标记数据已收到
        self.data_received.set()
        print(self.temp, self.hum, self.ppm)
    
    def val(self, block=False, timeout=None):
        # 传入block=True时会阻塞等待到收到第一份数据再返回
        if block:
            self.data_received.wait(timeout)
        print(self.temp, self.hum, self.ppm)
        return [self.temp, self.hum, self.ppm]
        
bar = Foo()
# 传入block=True参数,确保拿到更新后的数据再返回
print(bar.val(block=True))

你可以根据自己的使用场景选择调用方式:

  • 若需要调用val()时必须返回已更新的最新数据,调用时传入block=True即可
  • 若不需要阻塞,可在实例化后等待一段时间再调用val(),也能拿到更新后的数值

内容的提问来源于stack exchange,提问作者Lahiru Jayasundara

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 08:45:05