python 中的 Zeromq 列表或字典
在 python 中通过 Zeromq 发送列表或字典等对象的正确/最佳方法是什么? 如果我们使用 PUB/SUB 模式,其中字符串的第一部分将用作过滤器,该怎么办?
- 我知道存在多部分消息,但它们最初的目的不同。此外,您无法订阅以特定字符串作为第一个元素的所有消息。
What is the correct/best way to send objects like lists or dicts over zeromq in python?
What if we use a PUB/SUB pattern, where the first part of the string would be used as a filter?
- I am aware that there are multipart messages, but they where originally meant for a different purpose. Further you can not subscribe all messages, which have a certain string as the first element.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
手动序列化
您将数据转换为字符串、连接或其他,完成您的工作。它速度快,不占用太多空间,但需要工作和维护,而且不灵活。
如果另一种语言想要读取数据,则需要重新编码。没有干。
对于非常小的数据来说还可以,但实际上工作量通常是不值得的,除非您正在寻找速度和内存效率并且您可以衡量您的实现明显更好。
Pickle
速度慢,但可以序列化复杂对象,甚至可调用。它功能强大,而且非常简单,无需动脑筋。
另一方面,最终可能会得到一些你无法腌制和破坏代码的东西。另外,您无法与用其他语言编写的任何库共享数据。
最终,该格式不是人类可读的(很难调试)并且相当冗长。
非常适合共享对象和任务,但不太适合共享消息。
json
速度相当快,易于使用简单到一般复杂的数据结构来实现。它灵活、人类可读,并且可以轻松地跨语言共享数据。
对于复杂的数据,您必须编写一些代码。
除非您有非常具体的需求,否则这可能是功能和复杂性之间的最佳平衡。特别是因为 Python 库中的最后一个实现是用 C 语言实现的,而且速度还可以。
xml
冗长,难以创建并且维护起来很痛苦,除非您有一些可以为您完成所有工作的重型库。慢的。
除非有要求,否则我会避免它。
最后
现在像往常一样,速度和空间效率是相对的,你必须首先回答这个问题:
这才是最重要的。
哲学的美妙时刻过去了,使用 JSON。
Manual serialization
You turn the data into a string, concatenate or else, do your stuff. It's fast and doesn't take much space but requires work and maintenance, and it's not flexible.
If another language wants to read the data, you need to code it again. No DRY.
Ok for very small data, but really the amount of work is usually not worth it unless you are looking for speed and memory effiency and that you can measure that your implementation is significantly better.
Pickle
Slow, but you can serialize complex objects, and even callable. It's powerfull, and it's so easy it's a no brainer.
On the other side it's possible to end up with something you can't pickle and break your code. Plus you can't share the data with any lib written in an other language.
Eventually, the format is not human readable (hard do debug) and quite verbose.
Very nice to share objects and tasks, not so nice for messages.
json
Reasonably fast, easy to implement with simple to averagely complex data structures. It's flexible, human readible and data can be shared accross languages easily.
For complex data, you'll have to write a bit of code.
Unless you have a very specific need, this is probably the best balance between features and complexity. Espacially since the last implementation in the Python lib is in C and speed is ok.
xml
Verbose, hard to create and a pain to maintain unless you got some heavy lib that that does all the job for you. Slow.
Unless it's a requirement, I would avoid it.
In the end
Now as usual, speed and space efficiency is relative, and you must first answer the questions:
It's all what matters.
That wonderful moment of philosophy passed, use JSON.
JSON:
更多信息:
JSON:
More info:
在zeroMQ中,消息是简单的二进制blob。你可以在里面放任何你想要的东西。当您有一个包含多个部分的对象时,您需要首先将其序列化为可以在另一端反序列化的内容。最简单的方法是使用 obj.repr() ,它会生成一个字符串,您可以在另一端执行该字符串来重新创建对象。但这不是最好的方法。
首先,您应该尝试使用独立于语言的格式,因为迟早您需要与用其他语言编写的应用程序进行交互。 JSON 对象是一个不错的选择,因为它是可以由多种语言解码的单个字符串。但是,如果您通过网络发送大量消息,JSON 对象可能不是最有效的表示形式。相反,您可能需要考虑 MSGPACK 或 Protobufs 等格式。
如果您需要 PUB_SUB 的主题标识符,只需将其添加到开头即可。使用固定长度的主题,或者在主题和实际消息之间放置分隔符。
In zeroMQ, a message is simple a binary blob. You can put anything in it that you want. When you have an object that has multiple parts, you need to first serialize it into something that can be deserialized on the other end. The simplest way to do this is to use obj.repr() which produces a string that you can execute at the other end to recreate the object. But that is not the best way.
First of all, you should try to use a language independent format because sooner or later you will need to interact with applications written in other languages. A JSON object is a good choice for this because it is a single string that can be decoded by many languages. However, a JSON object might not be the most efficient representation if you are sending lots of messages across the network. Instead you might want to consider a format like MSGPACK or Protobufs.
If you need a topic identiffier for PUB_SUB, then simply tack it onto the beginning. Either use a fixed length topic, or place a delimiter between the topic and the real message.
发送前编码为 JSON,接收后解码为 JSON。
Encode as JSON before sending, and decode as JSON after receiving.
另请查看 MessagePack
http://msgpack.org/
“它就像 JSON。但又快又小”
Also check out MessagePack
http://msgpack.org/
"It's like JSON. but fast and small"
该问题中有几个问题,但就发送对象/迪克的最佳/正确方式而言,显然这取决于情况。对于很多情况,JSON 对于大多数人来说都很简单且熟悉。为了让它工作,我必须使用
send_string
和recv_string
例如文档中的讨论 https://pyzmq.readthedocs.io/en/latest/unicode.html
There are a few questions in that question but in terms of best / correct way to send objects / dics obviously it depends. For a lot of situations JSON is simple and familiar to most. To get it to work I had to use
send_string
andrecv_string
e.g.Discussion in docs https://pyzmq.readthedocs.io/en/latest/unicode.html
如果您有兴趣查看示例,我发布了一个名为 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/generate /zmq.core.socket.html
json 可能是最快的,如果您需要比 Zeromq 中包含的更快的速度,您可以手动使用 cjson。如果您注重速度,那么这是一个不错的选择。但是,如果您知道您将仅与其他 python 服务通信,那么 cPickle 的好处是原生 python 序列化格式,它为您提供了很多控制权。您可以轻松定义类以按照您想要的方式序列化,并最终得到本机 python 对象,而不是基本值。我确信如果您愿意,您也可以为 json 编写自己的对象挂钩。
In case you are interested in seeing examples, I released a small package called pyRpc that shows you how to do a simple python RPC setup where you expose services between different apps. It uses the python zeromq built-in method for sending and receiving python objects (which I believe is simply cPickle)
http://pypi.python.org/pypi/pyRpc/0.1
https://github.com/justinfx/pyRpc
While my examples use the pyobj version of the send and receive calls, you can see there are other versions available that you can use, like send_json, send_unicode... Unless you need some specific type of serialization, you can easily just use the convenience send/receive functions that handle the serialization/deserialization on both ends for you.
http://zeromq.github.com/pyzmq/api/generated/zmq.core.socket.html
json is probably the fastest, and if you need even faster than what is included in zeromq, you could manually use cjson. If your focus is speed then this is a good option. But if you know you will be communicating only with other python services, then the benefit of cPickle is a native python serialization format that gives you a lot of control. You can easily define your classes to serialize the way you want, and end up with native python objects in the end, as opposed to basic values. Im sure you could also write your own object hook for json if you wanted.