▶函数和异常
此模块定义了下列异常和函数:html
•exception struct.error
会在多种场合下被引起的异常;其参数为一个描述错误信息的字符串。python
•struct.pack(format, v1, v2, ...)
返回一个 bytes 对象,其中包含根据格式字符串 format 打包的值 v1, v2, ... 参数个数必须与格式字符串所要求的值彻底匹配。网络
•struct.pack_into(format, buffer, offset, v1, v2, ...)
根据格式字符串 format 打包 v1, v2, ... 等值并将打包的字节串写入可写缓冲区 buffer 从 offset 开始的位置。 请注意 offset 是必需的参数。函数
•struct.unpack(format, buffer)
根据格式字符串 format 从缓冲区 buffer 解包(假定是由 pack(format, ...) 打包)。 结果为一个元组,即便其只包含一个条目。
缓冲区的字节大小必须匹配格式所要求的大小,如 calcsize() 所示。布局
•struct.unpack_from(format, buffer, offset=0)
对 buffer 从 offset 开始的位置根据格式字符串 format 进行解包。 结果为一个元组,即便其只包含一个条目。 缓冲区的字节大小减去
offset 必须匹配格式所要求的大小,如 calcsize() 所示。编码
•struct.iter_unpack(format, buffer)code
根据格式字符串 format 交互式地从缓冲区 buffer 解包。 此函数返回一个迭代器,它将从缓冲区读取相同大小的块直至其内容所有耗尽。
缓冲区的字节大小必须整数倍于格式所要求的大小,如 calcsize() 所示。
每次迭代将产生一个如格式字符串所指定的元组。orm
▶3.4 新版功能.
struct.calcsize(format)
返回与格式字符串 format 相对应的结构的大小(亦即 pack(format, ...) 所产生的字节串对象的大小)。htm
▶格式字符串
格式字符串是用来在打包和解包数据时指定预期布局的机制。 它们使用指定被打包/解包数据类型的 格式字符 进行构建。
此外,还有一些特殊字符用来控制 字节顺序,大小和对齐方式。对象
字节顺序,大小和对齐方式
默认状况下,C类型以机器的本机格式和字节顺序表示,并在必要时经过跳过填充字节进行正确对齐(根据C编译器使用的规则)。
或者,根据下表,格式字符串的第一个字符可用于指示打包数据的字节顺序,大小和对齐方式:
•若是第一个字符不是其中之一,则假定为 '@' 。
•本机字节顺序可能为大端或是小端,取决于主机系统的不一样。 例如, Intel x86 和 AMD64 (x86-64) 是小端的;Motorola 68000 和 PowerPC G5 是大端的;ARM 和 Intel Itanium 具备可切换的字节顺序(双端)。 请使用 sys.byteorder 来检查你的系统字节顺序。
•本机大小和对齐方式是使用 C 编译器的 sizeof 表达式来肯定的。 这老是会与本机字节顺序相绑定。
•标准大小仅取决于格式字符;
•请注意 '@' 和 '=' 之间的区别:两个都使用本机字节顺序,但后者的大小和对齐方式是标准化的。
•格式 '!' 适合给那些宣称他们记不得网络字节顺序是大端仍是小端的可怜人使用。
•没有什么方式能指定非本机字节顺序(强制字节对调);请正确选择使用 '<' 或 '>'。
•注释:,
1,填充只会在连续结构成员之间自动添加。 填充不会添加到已编码结构的开头和末尾。
2,当使用非本机大小和对齐方式即 '<', '>', '=', and '!' 时不会添加任何填充。
3,要将结构的末尾对齐到符合特定类型的对齐要求,请以该类型代码加剧复计数的零做为格式结束。
▶格式字符
格式字符具备如下含义;C 和 Python 值之间的按其指定类型的转换应当是至关明显的。 ‘标准大小’列是指当使用标准大小时以字节表示的已打包值大小;
也就是当格式字符串以 '<', '>', '!' 或 '=' 之一开头的状况。 当使用本机大小时,已打包值的大小取决于具体的平台。
•在 3.3 版更改: 增长了对 'n' 和 'N' 格式的支持
•在 3.6 版更改: 添加了对 'e' 格式的支持。
注释:
1,'?' 转换码对应于 C99 定义的 _Bool 类型。 若是此类型不可用,则使用 char 来模拟。 在标准模式下,它老是以一个字节表示。
2,'q' 和 'Q' 转换码仅当平台的 C 编译器支持 C long long 或 Windows 上的 __int64 时才在本机模式下可用。 它们在标准模式下老是可用。
3,当尝试使用任何整数转换码打包一个非整数时,若是该非整数具备 __index__() 方法,则会在打包以前调用该方法将参数转换为一个整数。
在 3.2 版更改: 为非整数使用 __index__() 方法是 3.2 版的新增特性。
4,'n' 和 'N' 转换码仅对本机大小可用(选择为默认或使用 '@' 字节顺序字符)。 对于标准大小,你可使用适合你的应用的任何其余整数格式。
5,对于 'f', 'd' 和 'e' 转换码,打包表示形式将使用 IEEE 754 binary32, binary64 或 binary16 格式 (分别对应于 'f', 'd' 或 'e'),不管平台使用何种浮点格式。
6,'P' 格式字符仅对本机字节顺序可用(选择为默认或使用 '@' 字节顺序字符)。 字节顺序字符 '=' 选择使用基于主机系统的小端或大端排序。
struct 模块不会将其解读为本机排序,所以 'P' 格式将不可用。
7,IEEE 754 binary16 "半精度" 类型是在 IEEE 754 标准 的 2008 修订版中引入的。 它包含一个符号位,5 个指数位和 11 个精度位(明确存储 10 位),
能够彻底精确地表示大体范围在 6.1e-05 和 6.5e+04 之间的数字。 此类型并不被 C 编译器普遍支持:在一台典型的机器上,可使用 unsigned short 进行存储,
但不会被用于数学运算。 格式字符以前能够带有整数重复计数。 例如,格式字符串 '4h' 的含义与 'hhhh' 彻底相同。
•格式之间的空白字符会被忽略;可是计数及其格式字符中不可有空白字符。
•对于 's' 格式字符,计数会被解析为字节的长度,而不是像其余格式字符那样的重复计数;例如,'10s' 表示一个 10 字节的字节串,而 '10c' 表示 10 个字符。
若是未给出计数,则默认值为 1。 对于打包操做,字节串会被适当地截断或填充空字节以符合要求。 对于解包操做,结果字节对象老是刚好具备指定数量的字节。
做为特殊状况,'0s' 表示一个空字符串(而 '0c' 表示 0 个字符)。
•当使用某一种整数格式 ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q') 打包值 x 时,若是 x 在该格式的有效范围以外则将引起 struct.error。
•在 3.1 版更改: 在 3.0 中,某些包装了超范围值的整数格式会引起 DeprecationWarning 而不是 struct.error。
•'p' 格式字符用于编码“Pascal 字符串”,即存储在由计数指定的 固定长度字节 中的可变长度短字符串。 所存储的第一个字节为字符串长度或 255 中的较小值。
以后是字符串对应的字节。 若是传入 pack() 的字符串过长(超过计数值减 1),则只有字符串前 count-1 个字节会被存储。 若是字符串短于 count-1,
则会填充空字节以使得刚好使用了 count 个字节。 请注意对于 unpack(),'p' 格式字符会消耗 count 个字节,但返回的字符串永远不会包含超过 255 个字节。
•对于 '?' 格式字符,返回值为 True 或 False。 在打包时将会使用参数对象的逻辑值。 以本机或标准 bool 类型表示的 0 或 1 将被打包,任何非零值在解包时将为 True。
★使用例:
import struct
import binascii
import ctypes
values1 = (1, 'abc'.encode('utf-8'), 2.7)
values2 = ('defg'.encode('utf-8'),101)
s1 = struct.Struct('I3sf')
s2 = struct.Struct('4sI')
解释:元组数据 (1, 'abc'.encode('utf-8'), 2.7),包含int、string、float三种数据类型,而后定义了struct对象,
并制定了format‘I3sf’,I 表示int,3s表示三个字符长度的字符串,f 表示 float。
print(s1.size,s2.size)
prebuffer=ctypes.create_string_buffer(s1.size+s2.size)
print('Before : ',binascii.hexlify(prebuffer))
# t=binascii.hexlify('asdfaf'.encode('utf-8'))
# print(t)
s1.pack_into(prebuffer,0,*values1)
s2.pack_into(prebuffer,s1.size,*values2)
print('After pack',binascii.hexlify(prebuffer))
print(s1.unpack_from(prebuffer,0))
print(s2.unpack_from(prebuffer,s1.size))
s3=struct.Struct('ii')
s3.pack_into(prebuffer,0,123,123)
print('After pack',binascii.hexlify(prebuffer))
print(s3.unpack_from(prebuffer,0))
参考:https://docs.python.org/3/library/struct.html