списки или диктует над Zeromq в Python - PullRequest
9 голосов
/ 25 февраля 2012

Каков правильный / лучший способ посылать объекты, такие как списки или сообщения, через zeromq в python?Что, если мы используем шаблон PUB / SUB, где первая часть строки будет использоваться в качестве фильтра?

  • Я знаю, что существуют многокомпонентные сообщения, но они изначально предназначались для другогоцель.Кроме того, вы не можете подписаться на все сообщения, которые имеют определенную строку в качестве первого элемента.

Ответы [ 6 ]

15 голосов
/ 25 февраля 2012

Ручная сериализация

Вы превращаете данные в строку, объединяете или еще что-то делаете.Это быстро и не занимает много места, но требует работы и обслуживания, и это не гибко.

Если другой язык хочет прочитать данные, вам нужно снова их кодировать.Нет СУХОЙ.

Хорошо для очень маленьких данных, но на самом деле объем работы обычно не стоит того, если вы не ищете скорость и эффективность использования памяти и можете измерить, что ваша реализация значительно лучше.

Pickle

Медленно, но вы можете сериализовать сложные объекты и даже вызываться.Это мощно, и это так просто, что это не просто.

С другой стороны, возможно, что в итоге получится что-то, что вы не можете получить и сломать свой код.Кроме того, вы не можете делиться данными с любой библиотекой, написанной на другом языке.

В конце концов, формат не читается человеком (трудно делать отладку) и довольно многословен.

Очень приятно поделитьсяобъекты и задачи, не очень приятные для сообщений.

json

Достаточно быстро, легко реализуемо с простыми и средне сложными структурами данных.Она гибкая, удобочитаемая, и данные можно легко распространять на разные языки.

Для сложных данных вам придется написать немного кода.

Если у вас нет особых потребностей, это, вероятно, лучший баланс между функциями и сложностью.Особенно с тех пор, как последняя реализация в Python lib находится на C, а скорость в порядке.

xml

Многословно, сложно создать и трудно поддерживать, если у вас неттяжелая работа, которая делает всю работу за вас.Медленно.

Если бы это не было требованием, я бы его избегал.

В конце

Теперь, как обычно, скорость и эффективность пространства относительно,и вы должны сначала ответить на вопросы:

  • какая эффективность мне нужна?
  • что я готов заплатить (деньги, время, энергию) за это?
  • какое решение подходит для моей нынешней системы?

Это все, что имеет значение.

Этот чудесный момент философии прошел, используйте JSON.

7 голосов
/ 25 февраля 2012

В zeroMQ сообщение представляет собой простой двоичный объект.Вы можете положить в нее все, что захотите.Когда у вас есть объект, состоящий из нескольких частей, вам необходимо сначала сериализовать его в нечто, что можно десериализовать на другом конце.Самый простой способ сделать это - использовать obj.repr (), который создает строку, которую вы можете выполнить на другом конце, чтобы воссоздать объект.Но это не лучший способ.

Прежде всего, вы должны попытаться использовать независимый от языка формат, поскольку рано или поздно вам придется взаимодействовать с приложениями, написанными на других языках.JSON-объект является хорошим выбором для этого, потому что это одна строка, которая может быть декодирована многими языками.Однако объект JSON может быть не самым эффективным представлением, если вы отправляете много сообщений по сети.Вместо этого вы можете рассмотреть формат вроде MSGPACK или Protobufs.

Если вам нужен идентификатор темы для PUB_SUB, просто добавьте его в начало.Либо используйте тему фиксированной длины, либо поместите разделитель между темой и реальным сообщением.

6 голосов
/ 25 февраля 2012

Кодировать как JSON перед отправкой и декодировать как JSON после получения.

4 голосов
/ 02 сентября 2014

JSON:

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

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

Дополнительная информация:

4 голосов
/ 02 февраля 2013

Также проверьте MessagePack

http://msgpack.org/

«Это как JSON. Но быстро и мало»

2 голосов
/ 25 февраля 2012

На случай, если вам интересно посмотреть примеры, я выпустил небольшой пакет 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, если хотите.

...