python中struct 模块函数功能

struct 模块用于在 Python 值与二进制字节串(bytes 对象)之间进行转换,

它可以执行 Python 值和以 Python 字节对象表示的 C 结构之间的转换。Python不适合编写底层操作字节流的代码,但在对性能要求不高的地方,利用struct就方便多了。

主要功能包括:

  1. ‌打包(Packing)‌:将 Python 数据类型(如整数、浮点数、字符串)转换为二进制字节串。
  2. ‌解包(Unpacking)‌:从二进制字节串中解析出 Python 数据类型。
  3. ‌字节顺序控制‌:支持大端序(Big-Endian)和小端序(Little-Endian)字节序转换。

二、主要函数

以下是 struct 模块的核心函数及其用法:

函数名作用参数说明
struct.pack() 打包数据为字节串 format(格式字符串)+ v1, v2, ...(数据值)
struct.unpack() 解包字节串为数据 format(格式字符串)+ buffer(字节串)
struct.pack_into() 打包数据到缓冲区 format + buffer(可写缓冲区)+ offset(偏移量)+ v1, v2, ...
struct.unpack_from() 从缓冲区解包数据 format + buffer(字节串)+ offset=0(偏移量)
struct.calcsize() 计算格式字符串占用字节数 format(格式字符串)

三、格式字符串(Format Characters)

格式字符串用于定义数据类型和字节序,常见字符包括:

  • ‌整数类型‌:b(有符号8位)、B(无符号8位)、h(16位)、i(32位)、q(64位)。
  • ‌浮点数类型‌:f(单精度)、d(双精度)。
  • ‌字符串类型‌:s(字节串,需指定长度)。
  • ‌字节序控制‌:<(小端序)、>(大端序)、!(网络字节序)。

四、使用示例

pythonCopy Code
 
import struct
# 打包数据
data = struct.pack('<i2s', 123, b'ab')
# 小端序32位整数+2字节字符串
print(data) # 输出: b'\x7b\x00\x00\x00ab'
# 解包数据
unpacked = struct.unpack('<i2s', data)
print(unpacked) # 输出: (123, b'ab')
 
# 直接操作缓冲区
buffer = bytearray(10) struct.pack_into('<i2s', buffer, 0, 456, b'cd')
print(buffer)
# 输出: bytearray(b'\x00\x01\x01\x00cd\x00\x00\x00\x00')

五、注意事项

  1. ‌字节序‌:默认使用本地字节序,建议显式指定字节序(如<>)以保证跨平台兼容性。
  2. ‌字符串处理‌:s类型需指定长度,超出长度会截断,不足长度会填充\x00
  3. ‌缓冲区操作‌:pack_intounpack_from支持直接操作内存缓冲区(如bytearray)。

通过struct模块,可高效处理二进制数据,适用于文件I/O、网络通信、嵌入式系统交互等场景。

此模块定义了下列异常和函数:

exception struct.error

会在多种场合下被引发的异常;其参数为一个描述错误信息的字符串。

struct.pack(formatv1v2...)

返回一个 bytes 对象,其中包含根据格式字符串 format 打包的值 v1v2, ... 参数个数必须与格式字符串所要求的值完全匹配。

struct.pack_into(formatbufferoffsetv1v2...)

根据格式字符串 format 打包 v1v2, ... 等值并将打包的字节串写入可写缓冲区 buffer 从 offset 开始的位置。 请注意 offset 是必需的参数。

struct.unpack(formatbuffer)

根据格式字符串 format 从缓冲区 buffer 解包(假定是由 pack(format, ...) 打包)。 结果为一个元组,即使其只包含一个条目。 缓冲区的字节大小必须匹配格式所要求的大小,如 calcsize() 所示。

struct.unpack_from(format/bufferoffset=0)

对 buffer 从位置 offset 开始根据格式字符串 format 进行解包。 结果为一个元组,即使其中只包含一个条目。 缓冲区的字节大小从位置 offset 开始必须至少为 calcsize() 显示的格式所要求的大小。

struct.iter_unpack(formatbuffer)

根据格式字符串 format 以迭代方式从缓冲区 buffer 中解包。 此函数返回一个迭代器,它将从缓冲区读取大小相等的块直到其所有内容耗尽为止。 缓冲区的字节大小必须是格式所要求的大小的整数倍,如 calcsize() 所显示的。

 

格式字符串

格式字符串描述了打包和解包数据时的数据布局。 它们是使用 格式字符 来构建的,格式字符指明被打包/解包的数据的类型。 此外,还有用来控制 字节顺序、大小和对齐 的特殊字符。 每个格式字符串都是由一个可选的描述数据总体属性的前缀字符和一个或多个描述实际数据值和填充的格式字符组成的。

字节顺序,大小和对齐方式

在默认情况下,C 类型将以所在机器的原生格式和字节顺序来表示,并在必要时通过跳过填充字节来正确地对齐(根据 C 编译器所使用的规则)。 选择此行为是为了使已打包结构体的字节与对应的 C 结构体的内存布局完全对应。 使用原生字节顺序和填充还是标准格式取决于应用程序本身。

或者,根据下表,格式字符串的第一个字符可用于指示打包数据的字节顺序,大小和对齐方式:

字符

字节顺序

大小

对齐方式

@

按原字节

按原字节

按原字节

=

按原字节

标准

<

小端

标准

>

大端

标准

!

网络(=大端)

标准

如果第一个字符不是其中之一,则假定为 '@' 。

备注

 

数字 1023 (十六进制的 0x3ff) 具有以下字节表示形式:

  • 大端序 (>) 的 03 ff

  • 小端序 (<) 的 ff 03

Python 示例:

import struct
struct.pack('>h', 1023)
b'\x03\xff'
struct.pack('<h', 1023)
b'\xff\x03'

原生字节顺序可能为大端序或小端序,具体取决于主机系统。 例如,Intel x86, AMD64 (x86-64) 和 Apple M1 是小端序的;IBM z 和许多旧式架构则是大端序的。 请使用 sys.byteorder 来检查你的系统字节顺序。

本机大小和对齐方式是使用 C 编译器的 sizeof 表达式来确定的。 这总是会与本机字节顺序相绑定。

标准大小仅取决于格式字符;请参阅 格式字符 部分中的表格。

请注意 '@' 和 '=' 之间的区别:两个都使用本机字节顺序,但后者的大小和对齐方式是标准化的。

形式 '!' 代表网络字节顺序总是使用在 IETF RFC 1700 中所定义的大端序。

没有什么方式能指定非本机字节顺序(强制字节对调);请正确选择使用 '<' 或 '>'

注释:

  1. 填充只会在连续结构成员之间自动添加。 填充不会添加到已编码结构的开头和末尾。

  2. 当使用非本机大小和对齐方式即 '<', '>', '=', and '!' 时不会添加任何填充。

  3. 要将结构的末尾对齐到符合特定类型的对齐要求,请以该类型代码加重复计数的零作为格式结束。 参见 例子

格式字符

格式字符具有以下含义;C 和 Python 值之间的按其指定类型的转换应当是相当明显的。 ‘标准大小’列是指当使用标准大小时以字节表示的已打包值大小;也就是当格式字符串以 '<''>''!' 或 '=' 之一开头的情况。 当使用本机大小时,已打包值的大小取决于具体的平台。

格式

C 类型

Python 类型

标准大小

备注

x

填充字节

 

(7)

c

char

长度为 1 的字节串

1

 

b

signed char

整数

1

(1), (2)

B

unsigned char

整数

1

(2)

?

_Bool

bool

1

(1)

h

short

整数

2

(2)

H

unsigned short

整数

2

(2)

i

int

整数

4

(2)

I

unsigned int

整数

4

(2)

l

long

整数

4

(2)

L

unsigned long

整数

4

(2)

q

long long

整数

8

(2)

Q

unsigned long long

整数

8

(2)

n

ssize_t

整数

 

(3)

N

size_t

整数

 

(3)

e

(6)

float

2

(4)

f

float

float

4

(4)

d

double

float

8

(4)

F

float complex

复数

8

(10)

D

double complex

复数

16

(10)

s

char[]

字节串

 

(9)

p

char[]

字节串

 

(8)

P

void*

整数

 

(5)

在 3.3 版本发生变更: 增加了对 'n' 和 'N' 格式的支持

在 3.6 版本发生变更: 添加了对 'e' 格式的支持。

在 3.14 版本发生变更: 增加了对 'F' 和 'D' 格式的支持。

注释:

  1. '?' 转换码对应于自 C99 开始由 C 标准所定义的 _Bool 类型。 在标准模式下,它总是以一个字节来表示。

  2. 当尝试使用任何整数转换码打包一个非整数时,如果该非整数具有 __index__() 方法,则会在打包之前将参数转换为一个整数。

    在 3.2 版本发生变更: 增加了用于非整数的 __index__() 方法。

  3. 'n' 和 'N' 转换码仅对本机大小可用(选择为默认或使用 '@' 字节顺序字符)。 对于标准大小,你可以使用适合你的应用的任何其他整数格式。

  4. 对于 'f''d' 和 'e' 转换码,打包表示形式将使用 IEEE 754 binary32, binary64 或 binary16 格式 (分别对应于 'f''d' 或 'e'),无论平台使用何种浮点格式。

  5. 'P' 格式字符仅对本机字节顺序可用(选择为默认或使用 '@' 字节顺序字符)。 字节顺序字符 '=' 选择使用基于主机系统的小端或大端排序。 struct 模块不会将其解读为本机排序,因此 'P' 格式将不可用。

  6. IEEE 754 binary16 "半精度" 类型是在 IEEE 754 标准 的 2008 修订版中引入的。 它包含一个符号位,5 个指数位和 11 个精度位(明确存储 10 位),可以完全精确地表示大致范围在 6.1e-05 和 6.5e+04 之间的数字。 此类型并不被 C 编译器广泛支持:在一台典型的机器上,可以使用 unsigned short 进行存储,但不会被用于数学运算。 请参阅维基百科页面 half-precision floating-point format 了解详情。

  7. 在打包时,'x' 会插入一个 NUL 字节。

  8. 'p' 格式字符用于编码“Pascal 字符串”,即存储在由计数指定的 固定长度字节 中的可变长度短字符串。 所存储的第一个字节为字符串长度或 255 中的较小值。 之后是字符串对应的字节。 如果传入 pack() 的字符串过长(超过计数值减 1),则只有字符串前 count-1 个字节会被存储。 如果字符串短于 count-1,则会填充空字节以使得恰好使用了 count 个字节。 请注意对于 unpack()'p' 格式字符会消耗 count 个字节,但返回的字符串永远不会包含超过 255 个字节。

  9. 对于 's' 格式字符,计数会被解读为字节的长度,而不是像其他格式字符那样的重复计数;例如,'10s' 表示一个与特定的 Python 字节串互相映射的长度为 10 的字节数据,而 '10c' 则表示个 10 个与十个不同的 Python 字节对象互相映射的独立的一字节字符元素 (如 cccccccccc)。 (其中的差别的具体演示请参见 例子。) 如果未给出计数,则默认值为 1。 对于打包操作,字节串会被适当地截断或填充空字节以符合尺寸要求。 对于解包操作,结果字节对象总是会恰好具有指定数量的字节。 作为特例,'0s' 表示单个空字节串 (而 '0c' 表示 0 个字符)。

  10. 对于 'F' 和 'D' 格式字符,打包的表示形式使用 IEEE 754 binary32 和 binary64 格式来表示复数的各部分,不管平台是使用哪种浮点格式。 请注意复数类型 (F 和 D) 是无条件可用的,尽管复数类型在 C 中属于可选特性。 正如 C11 标准所指明的,每个复数类型都是由两个元素组成的 C 数组来表示的,其两个元素分别包含实部和虚部。

格式字符之前可以带有整数重复计数。 例如,格式字符串 '4h' 的含义与 'hhhh' 完全相同。

格式之间的空白字符会被忽略;但是计数及其格式字符中不可有空白字符。

当使用某一种整数格式 ('b''B''h''H''i''I''l''L''q''Q') 打包值 x 时,如果 x 在该格式的有效范围之外则将引发 struct.error

在 3.1 版本发生变更: 在之前版本中,某些整数格式包装了超范围的值并会引发 DeprecationWarning 而不是 struct.error

对于 '?' 格式字符,返回值为 True 或 False。 在打包时将会使用参数对象的逻辑值。 以本机或标准 bool 类型表示的 0 或 1 将被打包,任何非零值在解包时将为 True

 

参考: https://docs.python.org/zh-cn/3/library/struct.html

posted @ 2025-12-25 15:01  konglingbin  阅读(18)  评论(0)    收藏  举报