像 Java“实例过滤”这样的最 Pythonic 的消息处理方式是什么 [RabbitMQ]

Jor*_*rge 6 python java jms amqp rabbitmq

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

  Object object = myQueue.consume();
   if (object instanceof MessageA) {
      processMessageA((MessageA) object)
   } else if (object instanceof MessageB) {
      processMessageB((MessageB) object)
   }...
Run Code Online (Sandbox Code Playgroud)

所以现在我正在为 RabbitMQ 中的一些 Python 模块构建一个消息前端(主题通信)。我打算为不同消息将到达的每个消费者模块使用一个队列

我几乎拥有一切,但我仍在努力处理(消耗)消息。你如何区分消息类型?

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

Ori*_*hen 5

在用 Python 编程时,特别是对于那些来自 OO 语言的人来说,记住两个原则很重要。

首先,Python 不是面向对象的语言,它只支持类和对象。最 Pythonic 的方式通常是一种不依赖于类型和/或类的方式。

其次,有非常重要的“Python 之禅”。这组想法决定了 Python 语言本身的大部分构建方式,但也为我们这些使用它编程的人提供了条件。在这些想法中,有两个您应该始终努力实现。

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

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

最后,你应该记住python中的任何东西都是一个对象,包括函数,这意味着你可以使用映射作为操作字典:

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)

Run Code Online (Sandbox Code Playgroud)

这允许您在一个地方显式指定所有代码路径(这也称为策略模式)。它还具有额外的好处,您无需更改实际的处理代码。

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