python - 如何将自定义对象序列化/编码为字节/字节数组?
问题描述
我有以下python类:
class Header:
def __init__(self, id, len):
self.id = id
self.len = len
h = Header(1, 10)
如何将此类的实例序列化/编码h
为bytes
or 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(...)
。
解决方案
这称为序列化。
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
毫无疑问是要走的路。