一般可以用struct模块进行Python变量类型和Python bytes对象之间的转换。这可用于处理二进制数据流。
该模块有以下异常和函数:
异常:struct.error
该异常可能出现在所有地方; 参数是一个描述错误的字符串。
struct.pack(格式,v1,v2,... )
返回包含值v1,v2,... 的字节对象,根据格式字符串格式打包成字节流。参数的个数必须与格式所需的值完全匹配。
struct.pack_into(格式,缓冲区,偏移量,v1,v2,... )
根据格式字符串格式打包值v1,v2,... 。并将打包好的字节流写入可写缓冲区。请注意,偏移量是必需参数。
struct.unpack(格式,缓冲区)
根据格式字符串格式从缓冲区缓冲区解压缩。结果是一个元组,即使它只包含一个元素。缓冲区的大小(以字节为单位)必须与格式所需的大小相匹配。
struct.unpack_from(格式,缓冲区,偏移= 0 )
根据格式字符串格式从缓冲区偏移位置开始进行解压缩。结果是一个元组,即使它只包含一个元素。缓冲区的大小(以字节为单位,减去偏移量)至少为格式所需的大小。
struct.iter_unpack(格式,缓冲区)
根据格式字符串格式从缓冲区缓冲区中迭代解压缩。此函数返回一个迭代器,它将从缓冲区读取大小相同的块,直到其所有内容都被处理。缓冲区的大小(以字节为单位)必须是格式所需大小的倍数。每次迭代都会产生格式字符串指定的元组。
Python 3.4 以后才有的函数:
struct.calcsize(格式)
返回与格式字符串格式对应的 struct 的大小 。
字节顺序,大小和对齐
默认情况下,采用的C类型是和本机的格式和字节顺序一样的,可以在必要时通过跳过填充字节进行正确对齐(根据C编译器使用的规则)。格式字符串的第一个字符可用于指示打包数据的字节顺序,大小和对齐方式,如下表所示:
字符 | 字节顺序 | 大小 | 对齐方式 |
---|---|---|---|
@ | 依本机而定 | 依本机而定 | 依本机而定 |
= | 依本机而定 | 标准 | 空 |
< | 小端 | 标准 | 空 |
> | 大端 | 标准 | 空 |
! | 网络(=大端) | 标准 | 空 |
如果第一个字符不是其中之一,则默认它前面有个'@'。
依本机而定:字节顺序究竟是大端还是小端,取决于主机系统。例如,Intel x86和AMD64(x86-64)是小端; 摩托罗拉68000和PowerPC G5都是大端的; ARM和Intel Itanium是可切换的字节序(双端)。使用sys.byteorder来检查你系统的字节序。
需要注意的区别'@'和'=':都使用本地字节顺序,但后者的大小和排列是标准化的。
该表格'!'适用于那些声称无法记住网络字节顺序是大端还是小端的人。
使用'<'或'>'可以自定义字节顺序。
格式字符
根据变量类型,C和Python值之间的转换应该是很简单的。字节数列是指使用标准大小时打包值的大小(以字节为单位); 也就是说,当格式字符串中的格式字符前有'<','>','!'或 '='标记时,打包值的大小取决于平台,不取决于主机。
Format | C Type | Python type | 字节数 |
---|---|---|---|
x | pad byte | no value | |
c | char | string of length 1 | 1 |
b | signed char | integer | 1 |
B | unsigned char | integer | 1 |
? | _Bool | bool | 1 |
h | short | integer | 2 |
H | unsigned short | integer | 2 |
i | int | integer | 4 |
I | unsigned int | integer or lon | 4 |
l | long | integer | 4 |
L | unsigned long | long | 4 |
q | long long | long | 8 |
Q | unsigned long long | long | 8 |
n | ssize_t | integer | |
N | size_t | integer | |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | string | |
p | char[] | string | |
P | void * | long |
在python 3.3版本:新增'n'和'N'格式。
格式字符是可以重复计数。例如,格式字符串'4h'表示与'hhhh'完全相同。
举个例子:
>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8