Python:使用结构模块处理包含数组的结构
Python: Handling structs containing arrays with the struct module
虽然 struct
模块使处理包含标量值的类 C 结构变得非常简单,但我看不出如何明智地处理包含数组的结构。
例如,如果我有以下 C 结构:
struct my_struct {
int a1[6];
double a2[3];
double d1;
double d2;
int i1;
int i2;
int a3[6];
int i3;
};
并希望解压其值并使用相同的变量(a1
、a2
、a3
、d1
、d2
、i1
, i2
, i3
) 在 Python 中,我 运行 遇到的问题是 struct
只是分别给我一个元组中的每个值。所有关于哪些值应该分组在数组中的信息都丢失了:
# doesn’t work!
a1, a2, d1, d2, i1, i2, a3, i3 = struct.unpack(
'6i3dddii6ii', b'abcdefghijklmnopqrstuvwxy' * 4
)
相反,我必须手动对元组进行切片和分离,这是一个非常繁琐且容易出错的过程:
t = struct.unpack('6i3dddii6ii', b'abcdefghijklmnopqrstuvwxy' * 4)
a1 = t[:6]
a2 = t[6:9]
d1, d2, i1, i2 = t[9:13]
a3 = t[13:19]
i3 = t[19]
有没有更好的方法来处理 struct
的数组?
您可以使用 construct library,它几乎包装了 struct
模块,使解析和构建二进制数据更加方便。
这是一个基本示例:
import construct
my_struct = construct.Struct(
"a1" / construct.Array(6, construct.Int32sl),
"a2" / construct.Array(3, construct.Float64l),
"d1" / construct.Float64l,
"d2" / construct.Float64l,
"i1" / construct.Int32sl,
"i2" / construct.Int32sl,
"a3" / construct.Array(6, construct.Int32sl),
"i3" / construct.Int32sl
)
parsed_result = my_struct.parse(b'abcdefghijklmnopqrstuvwxy' * 4)
# now all struct attributes are available
print(parsed_result.a1)
print(parsed_result.a2)
print(parsed_result.i3)
assert 'a1' in parsed_result
assert 'i3' in parsed_result
虽然 struct
模块使处理包含标量值的类 C 结构变得非常简单,但我看不出如何明智地处理包含数组的结构。
例如,如果我有以下 C 结构:
struct my_struct {
int a1[6];
double a2[3];
double d1;
double d2;
int i1;
int i2;
int a3[6];
int i3;
};
并希望解压其值并使用相同的变量(a1
、a2
、a3
、d1
、d2
、i1
, i2
, i3
) 在 Python 中,我 运行 遇到的问题是 struct
只是分别给我一个元组中的每个值。所有关于哪些值应该分组在数组中的信息都丢失了:
# doesn’t work!
a1, a2, d1, d2, i1, i2, a3, i3 = struct.unpack(
'6i3dddii6ii', b'abcdefghijklmnopqrstuvwxy' * 4
)
相反,我必须手动对元组进行切片和分离,这是一个非常繁琐且容易出错的过程:
t = struct.unpack('6i3dddii6ii', b'abcdefghijklmnopqrstuvwxy' * 4)
a1 = t[:6]
a2 = t[6:9]
d1, d2, i1, i2 = t[9:13]
a3 = t[13:19]
i3 = t[19]
有没有更好的方法来处理 struct
的数组?
您可以使用 construct library,它几乎包装了 struct
模块,使解析和构建二进制数据更加方便。
这是一个基本示例:
import construct
my_struct = construct.Struct(
"a1" / construct.Array(6, construct.Int32sl),
"a2" / construct.Array(3, construct.Float64l),
"d1" / construct.Float64l,
"d2" / construct.Float64l,
"i1" / construct.Int32sl,
"i2" / construct.Int32sl,
"a3" / construct.Array(6, construct.Int32sl),
"i3" / construct.Int32sl
)
parsed_result = my_struct.parse(b'abcdefghijklmnopqrstuvwxy' * 4)
# now all struct attributes are available
print(parsed_result.a1)
print(parsed_result.a2)
print(parsed_result.i3)
assert 'a1' in parsed_result
assert 'i3' in parsed_result