Python MQTT订阅出现NameError: name 'msg' is not defined如何解决
错误原因
- 触发
NameError: name 'msg' is not defined的核心是10秒等待周期内没有收到Sekurit_KTBlower_Optimizer_write主题的消息,on_message回调从未执行,全局变量msg未被创建就被调用。 - 提前声明
msg = None后仍报错的两个原因:- 10秒内仍未收到消息时
msg仍为None,执行None.decode()会直接抛出异常 - 原
on_message逻辑错误将bytes类型的message.payload转为str后赋值,str类型不存在decode()方法,后续转码步骤必然失败
- 10秒内仍未收到消息时
- 额外隐藏错误:变量名大小写不统一,代码中定义的键为
Upperpredict,打印时误写为UpperPredict,会触发二次命名错误。
可行解决方案
调整逻辑如下:
- 提前初始化全局消息变量和接收状态标记,避免未定义错误
- 修正回调赋值逻辑,直接存储原始
bytes类型的 payload,不要提前转字符串 - 替换固定10秒休眠逻辑,新增消息接收校验,确认收到有效消息后再执行后续解析步骤
- 统一变量名大小写,新增异常捕获兼容异常场景
修正后完整代码
import paho.mqtt.client as mqtt import time import ast # 提前初始化全局变量 msg = None msg_received = False def on_message(client, userdata, message): global msg, msg_received # 直接存储bytes类型payload,不要提前转str msg = message.payload msg_received = True print(f"收到主题{message.topic}的消息") broker_address="10.87.7.27" print("创建MQTT实例") client = mqtt.Client("P1") client.on_message = on_message print("连接MQTT broker") client.connect(broker_address, 1883) client.loop_start() print("订阅主题 Sekurit_KTBlower_Optimizer_write") client.subscribe("Sekurit_KTBlower_Optimizer_write") # 等待消息,最多等10秒 wait_timeout = 10 start_time = time.time() while not msg_received and time.time() - start_time < wait_timeout: time.sleep(0.5) if not msg_received: print("超时未收到有效消息,退出程序") else: try: dict_str = msg.decode("UTF-8") mydata = ast.literal_eval(dict_str) Lowerpredict = mydata["Lowerpredict"] Upperpredict = mydata["Upperpredict"] print(Lowerpredict, Upperpredict) except Exception as e: print(f"消息解析失败:{e}") client.loop_stop() client.disconnect()
运行注意事项
- 确认MQTT broker地址
10.87.7.27可正常访问,端口1883未被防火墙拦截 - 确认10秒超时周期内有设备向
Sekurit_KTBlower_Optimizer_write主题推送符合格式的消息 - 若推送的是标准JSON格式,可替换
ast.literal_eval为json.loads,兼容性更好
内容的提问来源于stack exchange,提问作者Arya
相关产品推荐
相关产品推荐

