在python中通过zeromq列出或表示

时间:2012-02-25 15:35:13

标签: python zeromq

在python中通过zeromq发送列表或dicts等对象的正确/最佳方法是什么? 如果我们使用PUB / SUB模式,该字符串的第一部分将用作过滤器,该怎么办?

  • 我知道有多部分消息,但它们最初用于不同目的。此外,您无法订阅所有消息,这些消息具有特定字符串作为第一个元素。

7 个答案:

答案 0 :(得分:15)

手动序列化

您将数据转换为字符串,连接或其他,做你的东西。它速度快,占用空间不大,但需要工作和维护,而且不灵活。

如果另一种语言想要读取数据,则需要再次编码。没干。

确定非常小的数据,但实际上工作量通常不值得,除非您正在寻找速度和内存效率,并且您可以衡量您的实施是否明显更好。

<强>味酸

慢,但你可以序列化复杂的对象,甚至可以调用。它功能强大,而且非常简单,这是一个不费吹灰之力。

另一方面,最终可能会出现一些你无法挑剔的东西并破坏你的代码。此外,您无法与使用其他语言编写的任何lib共享数据。

最终,格式不是人类可读的(难以调试)并且非常详细。

分享对象和任务非常好,对消息不太好。

<强> JSON

使用简单到平均复杂的数据结构,合理快速,易于实现。它灵活,人类可读,数据可以轻松地与语言共享。

对于复杂数据,您必须编写一些代码。

除非您有非常具体的需求,否则这可能是功能和复杂性之间的最佳平衡。特别是因为Python lib中的最后一个实现是在C中,速度还可以。

<强> XML

详细,难以创造并且难以维持,除非你有一些重型文件可以为你完成所有工作。慢。

除非是要求,否则我会避免它。

最后

现在像往常一样,速度和空间效率是相对的,你必须首先回答问题:

  • 我需要什么样的效率?
  • 我准备为此付出的代价(金钱,时间,精力)?
  • 什么解决方案适合我当前的系统?

重要的是这一切。

哲学的美好时刻过去了,使用JSON。

答案 1 :(得分:7)

在zeroMQ中,消息很简单,就是二进制blob。你可以在里面放任何你想要的东西。如果有一个具有多个部分的对象,则需要先将其序列化为可在另一端进行反序列化的内容。最简单的方法是使用obj.repr()生成一个字符串,您可以在另一端执行该字符串来重新创建该对象。但这不是最好的方式。

首先,您应该尝试使用与语言无关的格式,因为您迟早需要与其他语言编写的应用程序进行交互。 JSON对象是一个很好的选择,因为它是一个可以被许多语言解码的单个字符串。但是,如果要通过网络发送大量消息,则JSON对象可能不是最有效的表示形式。相反,您可能需要考虑像MSGPACK或Protobufs这样的格式。

如果您需要PUB_SUB的主题标识符,那么只需将其添加到开头即可。使用固定长度的主题,或在主题和真实消息之间放置分隔符。

答案 2 :(得分:6)

在发送之前编码为JSON,并在接收后解码为JSON。

答案 3 :(得分:4)

另请查看MessagePack

http://msgpack.org/

“它就像JSON。但又快又小”

答案 4 :(得分:4)

JSON:

# Client
socket.send(json.dumps(message))

# Server
message = json.loads(socket.recv())

更多信息:

答案 5 :(得分:2)

如果您有兴趣看到示例,我发布了一个名为pyRpc的小包,它向您展示了如何在不同应用程序之间公开服务的简单python RPC设置。它使用python zeromq内置方法发送和接收python对象(我​​相信它只是cPickle)

http://pypi.python.org/pypi/pyRpc/0.1

https://github.com/justinfx/pyRpc

虽然我的示例使用了发送和接收调用的pyobj版本,但您可以看到还有其他可用的版本,例如send_json,send_unicode ...除非您需要某些特定类型的序列化,否则您可以轻松地使用方便的发送/接收函数来处理两端的序列化/反序列化。

http://zeromq.github.com/pyzmq/api/generated/zmq.core.socket.html

json可能是最快的,如果你需要比zeromq中包含的更快,你可以手动使用cjson。如果您的重点是速度,那么这是一个不错的选择。但是如果你知道你只会与其他python服务进行通信,那么cPickle的好处是一个原生的python序列化格式,可以为你提供很多控制。您可以轻松地定义类以按您希望的方式序列化,最后使用本机python对象,而不是基本值。我相信如果你愿意,你也可以为json编写自己的对象钩子。

答案 6 :(得分:0)

该问题中有几个问题,但是就最佳/正确的方式发送对象/ dic而言,显然这取决于。在很多情况下, JSON 很简单,而且大多数人都很熟悉。要使其正常工作,我必须使用send_stringrecv_string例如

# client.py

socket.send_string(json.dumps({'data': ['a', 'b', 'c']}))
# server.py

result = json.loads(socket.recv_string())

讨论文档https://pyzmq.readthedocs.io/en/latest/unicode.html