问题描述
我正在与另一个使用msgpack的系统通信。 一直在尝试使用msgpack python软件包打包和解包自定义对象。但是没有正确地做到这一点。
消息是数组,其结构如下:
[Header,Payload]
此处在我称为Message
的类中定义。
Header是长度为两个整数[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}")
其中有效负载定义为带有字典的类:
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
的对象。
我正在使用随pip一起安装的python 3.6和msgpack 1.0.0。
解决方法
在这里留下答案,以防以后有人听到。 解决方案是将拆包与解码分开。 原始类型会自动解压缩,而无需特殊的解码功能。
因此在示例中,可以直接对该字典进行编码和解码:
sort_list
您需要的是简单地调用O(N * M * log(M) + N * log(N))
而没有对象挂钩函数。
{
7: {8: 0.1},1: {1: 1.3}
}
然后您可以编写一个用于解码的函数,以获取该字典并将其解码。