首页 > 解决方案 > 如何将自定义对象序列化/编码为字节/字节数组?

问题描述

我有以下python类:

class Header:
  def __init__(self, id, len):
    self.id = id
    self.len = len

h = Header(1, 10)

如何将此类的实例序列化/编码hbytesor bytearray,例如可以写入到socket?

为了提供更多的视角,我需要将此对象写入一个 unix 域套接字,其中 C++ 程序正在侦听以接收上述对象(它struct完全如上定义上述对象,具有相同数量/类型的字段)。编码方式pickle.dump(...)不起作用。

C++结构是:

typedef struct Header {
  uint32_t id;
  uint32_t len;
}

事实上,我可以从 与该C++程序进行交互Go,如下所示。

import (
  "bytes"
  "encoding/binary"
)

type Header struct {
  ID uint2
  Len uint32
}

// output of this function is written to the socket opened by C++ and it works!!
func GetHeaderBuf() *bytes.Buffer, error{
  hdrBuf := new(bytes.Buffer)
  hdr := Header{1, 10}
  if err := binary.Write(hdrBuf, binary.LittleEndian, hdr); err != nil {
    return nil, err
  }
  return hdrBuf, nil
}

我正在寻找的Go是上面代码行的 python 等价物binary.Write(...)

标签: pythonc++python-3.xgo

解决方案


这称为序列化

pickle在 Python 中,您可以使用自动执行(反)序列化或手动序列化的标准库模块。在后一种情况下,您决定要编码的各个属性以及编码它们的方式。然后struct模块进行实际的字节转换。

pickle方法:

data = pickle.dumps(h)
h2 = pickle.loads(data)

手动方式:

假设我们需要 2 个字节来存储一个 id(小于 65636)和 4 个字节来存储一个 len。我们可以做

data = struct.pack('>hi', h.ID, h.Len)
h2 = Header(*struct.unpack('>hi', data))

Pickling 使用内部格式,只能在 Python 应用程序之间使用。另一方面,struct它特别适合异构应用程序。这里>说整数值应该使用所谓的网络顺序(大)字节序。这简化了在不同架构之间交换值的过程。

如果另一部分使用C语言,struct毫无疑问是要走的路。


推荐阅读