Python 中具有类似-c 属性的结构

Structure with attribute like-c in Python

我想在 C 中创建类似于结构的东西,但在 Python 中。具体来说,我想这样:

typedef struct __attribute__((__packed__)) 
{
    float x[4];
    uint8 y;
    int z;
} structName;

在 Python 中。我在某处读到我可以使用命名元组但想避免填充,但我不知道如何在 Python 中进行填充。谁能告诉我该怎么做?我会在UDP通信中使用它。

如果你想序列化(例如:保存到文件或通过网络发送),你应该检查 struct 库基本上你可以定义如何保存你的数据,多少字节和顺序。

您可以在 python 中使用 class 来表示您的结构,并添加两个函数以将其打包成较小的二进制数据,并在您再次需要时从中解压

你的例子应该是:

import struct

class StructName():
    def __init__(self, xs=None, y=None, z=None):
        self.xs = xs
        self.y = y
        self.z = z

    def pack(self):
        return struct.pack("!4fBi", *self.xs, self.y, self.z)

    def unpack(self, packed_bytes):
        *self.xs, self.y, self.z = struct.unpack("!4fBi", packed_bytes)

if __name__ == "__main__":
    s = StructName([1.0, 0.5, 2.0, 0.], 255, 42)
    tmp = StructName()
    bytedata = s.pack()
    print("s", s.xs, s.y, s.z) # s [1.0, 0.5, 2.0, 0.0] 255 42
    print(len(bytedata), bytedata) # 21 b'\x00\x00\x80?\x00\x00\x00?\x00\x00\x00@\x00\x00\x00\x00\xff\x00\x00\x00*\x00\x00\x00'
    tmp.unpack(bytedata)  # fill data into tmp class
    tmp.xs[0] = 42.5
    print("tmp", tmp.xs, tmp.y, tmp.z) # tmp [42.5, 0.5, 2.0, 0.0] 255 42

packunpack 函数中的格式字符串是 "!4fBi" 其中:

  • ! - 使用网络字节序 (bigendian)
  • 4f - 四个浮点数(4*4 字节)
  • B - 一个无符号字符(1 字节)
  • i - 一个有符号整数(4 字节)

有关更多信息,请查看此部分:Format Characters

在已接受答案的评论部分回答评论

import re
import struct


def get_values_from_binary(format_str, bin_data):
    val_regex = re.compile(r"[a-zA-Z]([0-9]+)?")
    ls = struct.unpack(format_str, bin_data)
    res = []
    i = 0
    for m in val_regex.finditer(format_str):
        groups = m.groups()
        current_length = 1
        if groups is not None and groups[0] is not None:
            current_length = int(groups[0])
        res.append(ls[i:i + current_length])
        i += current_length
    return res


if __name__ == "__main__":
    f_str = "<I7f7f7f3f4ffI"
    data = [0]*7 + [0.3]*7 + [0.5]*7 + [0.9]*3 + [1.0]*4 + [2.5, 3.5, 1]
    print(data)
    bindata = struct.pack(f_str, *data)
    unpacked_data = get_values_from_binary(f_str, bindata)
    print(unpacked_data)