Чтобы упростить обратные вызовы mqtt и сохранить исходный обратный вызов on_message настолько чистым и читаемым, насколько это возможно, существует механизм обратных вызовов, который помогает пользователям генерировать обратные вызовы простым способом, как показано ниже.
@CallbackMechanism.make_callback("client1", "topic.split('/')[1] == 'callback'")
def callback_trigger(topic, payload):
print("callback has been triggered")
print("do something")
Приведенный выше декоратор принимает первый аргумент в качестве идентификатора клиента mqtt, для которого пользователь хочет, чтобы был вызван обратный вызов, а следующий аргумент является выражением, которое, если оно оценивается как true, запускает обратный вызов.Если сервис / модуль состоит из нескольких обратных вызовов, которые должны запускаться из разных условий, это делает создание обратных вызовов простым и чистым с точки зрения пользователя.
Механизм обратного вызова - это класс, который оборачивает исходную функцию обратного вызова on_message, что делает его достаточно гибким для пользователя, чтобы использовать механизм для генерации обратных вызовов или инициировать обратные вызовы из исходной функции on_message, что опять-таки может привести к множественным if /еще условия и сложная функция, просто говорю.
Механизм обратного вызова
class CallbackMechanism:
callbackFunctionsTriggers = {}
@classmethod
def wrap_on_message(cls, on_message_func):
def wrapped_on_message(*args):
client = args[0]
msg = args[2]
clientId = str(client._client_id)[2:-1]
topic = msg.topic
payload = str(msg.payload)[2:-1]
on_message_func(topic, payload)
for condition, callback in cls.callbackFunctionsTriggers[
clientId].items():
if eval(condition):
callback(topic, payload)
return wrapped_on_message
@classmethod
def make_callback(cls, clientId, condition):
def decorator(callbackFunc):
if clientId not in cls.callbackFunctionsTriggers:
cls.callbackFunctionsTriggers[clientId] = {}
cls.callbackFunctionsTriggers[clientId][condition] = callbackFunc
return callbackFunc
return decorator
Пользователь
@CallbackMechanism.wrap_on_message
def on_message(topic, payload):
print("topic --> ", topic)
print("payload --> ", payload)
print("do anything")
@CallbackMechanism.make_callback("client1", "topic.split('/')[1] == 'callback'")
def callback_trigger(topic, payload):
print("callback has been triggered")
print("do something")
- , если есть, скажем, 20-30 обратных вызововкоторые должны запускаться из разных условий, основанных на разных темах и полезных нагрузках, исходная функция on_message будет загрязнена сложным if / else и станет длинной функцией.Что вы думаете о вышеуказанном механизме?Может ли быть лучший подход к проблеме усложнения множественных условий обратного вызова и их вызова внутри одной функции?
- Этот механизм работает для функций уровня модуля.Но как заставить вышесказанное работать для методов экземпляра класса.Обратный вызов в приведенном ниже коде не запускается, так как ему нужен сам объект в качестве первого аргумента, который не может быть предоставлен через обернутый on_message.Так как заставить это работать через тот же механизм?Как передать аргумент self при срабатывании обратного вызова?Смотрите код ниже -
import CallbackMechanism # the same class will be used by all modules for generating callbacks
class AnyClass:
@CallbackMechanism.make_callback("client1", "topic.split('/')[2] == 'class'")
def callback_inside_class(self, topic, payload):
print("this is callback inside class")
anyClassObject = AnyClass()