Python Paho接收Topic B消息后发布Topic A报错AttributeError
解决MQTT回调中
AttributeError: 'NoneType' object has no attribute 'publish'的问题 你这明显是踩了类方法作为MQTT回调时的参数顺序坑!问题根源出在on_message方法的参数定义,以及MQTT客户端库(大概率是paho-mqtt)的回调参数传递逻辑上。
问题原因拆解
你把on_message定义成了类的方法:
def on_message(self, client, message): if(message.payload === condition): client.publish("TOPIC/A", payload="YES", retain=False)
但paho-mqtt的on_message回调标准签名是:def on_message(client, userdata, message):。当你把类方法注册为回调时,库并不会自动把self作为第一个参数传入——它会把MQTT客户端实例作为第一个参数,第二个参数是你设置的userdata(默认是None),第三个才是消息对象。
所以你的代码里,self参数实际接收到的是MQTT客户端实例,而client参数拿到的是None(因为没设置userdata),这就导致调用client.publish()时,本质是在对None调用方法,自然触发AttributeError。
两种修复方案
方案1:修正回调参数签名(推荐)
调整on_message的参数顺序,同时把类实例作为userdata传入客户端,这样既能符合库的要求,又能访问类的属性:
import paho.mqtt.client as mqtt class YourMQTTManager: def __init__(self): self.client = mqtt.Client() # 将当前类实例设置为userdata,方便回调中访问 self.client.user_data_set(self) # 注册回调方法 self.client.on_message = self.on_message # 按照库的标准签名定义:client, userdata, message def on_message(self, client, userdata, message): # userdata就是当前类的实例,可用来访问其他属性 self_instance = userdata # 注意Python用==而非===,且payload是字节类型,需匹配格式 if message.payload == b"your_target_condition": client.publish("TOPIC/A", payload="YES", retain=False)
方案2:用Lambda绑定self(快速临时修复)
如果你不想改动参数签名,可以用Lambda包装回调,手动传入self:
import paho.mqtt.client as mqtt class YourMQTTManager: def __init__(self): self.client = mqtt.Client() # 用Lambda包装,把self传入自定义的回调参数中 self.client.on_message = lambda client, userdata, msg: self.on_message(client, msg) def on_message(self, client, message): if message.payload == b"your_target_condition": client.publish("TOPIC/A", payload="YES", retain=False)
额外提醒
- Python中判断相等用
==而不是===,你代码里的message.payload === condition会直接报错,记得修正。另外payload默认是字节类型,要和你的条件值格式匹配(比如转成b"xxx"或解码为字符串)。 - 确保回调注册在客户端连接之前,且客户端实例没有被意外置为
None。
内容的提问来源于stack exchange,提问作者user8951490
相关产品推荐
相关产品推荐

