Я общаюсь с другой системой, которая использует msgpack. Пытались упаковать и распаковать пользовательские объекты с помощью пакета msgpack python. Но сделать это как следует не удалось.
Сообщения, которые представляют собой массивы, имеют следующую структуру:
[Header, Payload]
здесь определено в классе, который я называю Message
.
Заголовок представляет собой массив длиной два целых числа [number, type]
. Payload
однако это карта с целочисленными ключами. Внутри Payload
также есть карты с целыми ключами. Итак, у меня может быть полезная нагрузка, которая выглядит так:
{
7: {8: 0.1},
1: {1: 1.3}
}
Я написал метод для кодирования такого сообщения
def encode(obj):
if isinstance(obj, Message):
return [obj.header, obj.payload]
elif isinstance(obj, Header):
return [obj.number, obj.type]
elif isinstance(obj, Payload):
return obj.data
raise ValueError(f"Wrong input for message. This object is given {obj}")
где Payload определяется как класс со словарем:
class Payload:
def __init__(self) -> None:
self.data = {}
Я могу закодировать сообщение с помощью
message = Message()
packed = msgpack.packb(message, default=encode)
Но я не могу расшифровать его с помощью msgpack.unpackb
. Основываясь на короткой документации, я расшифровываю так
unpacked = msgpack.unpackb(packed, object_hook=decode, strict_map_key=False)
Чего я не знаю, так это того, как правильно написать метод декодирования. Если я определяю функцию decode
следующим образом:
def decode(packed_obj):
print(f'decode called with {packed_obj}')
Я получаю этот вывод
decode called with {8: 0.1}
decode called with {1: 1.3}
decode called with {1: None, 7: None}
Кажется, что msgpack начинает с вызова метода для самых глубоких словарей, а затем продвигается вверх. Но я изо всех сил пытаюсь восстановить объект Payload
.
Я думал, что смогу просмотреть действительные ключи, и если значение является числом с плавающей запятой, то я знаю, что это внутренний словарь. Но функция декодирования должна в итоге вернуть объект класса Message
.
Я использую python 3.6 и msgpack 1.0.0, который устанавливается вместе с pip.