msgpack python自定义对象

问题描述

我正在与另一个使用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}
}

然后您可以编写一个用于解码的函数,以获取该字典并将其解码。