Python编辑字节流

一般可以用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