像这样处理消息的最 Pythonic 方式是什么 Java "instance-filtering" [RabbitMQ]

What is the most Pythonic way of processing messages like this Java "instance-filtering" [RabbitMQ]

来自 Java 背景,在开发由 JMS 连接的服务时,我曾经处理消息并通过检查它们的类型来区分它们,例如(简化):

  Object object = myQueue.consume();
   if (object instanceof MessageA) {
      processMessageA((MessageA) object)
   } else if (object instanceof MessageB) {
      processMessageB((MessageB) object)
   }...

所以现在我正在为 RabbitMQ 中的某些 Python 模块构建消息传递 front-end(主题通信)。我计划为每个 consumer-module 使用 一个 queue 不同的消息 将到达。

我几乎拥有一切,但我仍在为处理(消费)消息而苦苦挣扎。您如何区分消息类型?

我想过自定义 JSON headers,但我不知道这是否正确。

在使用 python 编程时,特别是对于使用 OO 语言的人来说,牢记两个原则很重要。

首先,Python不是面向对象的语言,它只支持类和object。最 pythonic 的方法通常是不依赖于键入的方法 and\or 类.

其次,还有all-important"Zen of Python"。这套想法决定了 Python 语言本身的大部分构建方式,但也为我们这些使用它编程的人提供了帮助。在这些想法中,有两个是您应该始终努力实现的。

  • 显式优于隐式。
  • 简单胜于复杂。

使用这些想法,我将尝试展示我认为最好的方法,这种方法确实使用了 JSON headers。明确意味着我们应该清楚地说明我们要做什么,而简单意味着我们应该把它写在最合乎逻辑的地方。我认为这直接指向 JSON 本身中的类型是实现这个想法的最明确和最简单的方法。 此外,我假设您的消息类型之间存在差异,并且不在 header 中说明类型将需要您编写一些代码来区分 then 基于一些模糊的差异,再次破坏明确性的概念。

要关闭,您应该记住 python 中的任何内容都是 object,包括函数 ,这意味着您可以将地图用作操作字典:

message_to_action_map = {
    'typeA': functionA,
    'typeB': functionB
}

def consumer_callback(msg):
    # In Python, RabbitMQ works by push and not by pull
    process = message_to_action_map[msg['type']]
    process(msg)

这使您可以在一处显式指定所有代码路径(这也称为 Strategy 模式)。它还具有您无需更改实际处理代码的额外好处。

简而言之,我认为使用消息 headers 确实是区分消息的最 pythonic 方式,因为它比任何其他方式都更简单、更明确。