Python struct模块详解:二进制数据的打包与解包实践

阿橙
阿橙
发布时间:2026-10-12| 2人浏览过
原创

Python标准库中的struct模块专用于二进制数据的打包与解包,广泛适用于网络通信、底层协议解析及C语言结构体交互。本文系统讲解format格式映射、字节序控制前缀,演示pack与unpack核心流程,并提供calcsize、缓冲流写入及Struct预编译优化方案,助力开发者高效处理定长字节流。

二进制数据的打包与解包基础

在处理非文本形式的底层数据交换时,Python内置的struct模块能够精确地将Python原生数据类型转换为固定长度的字节流(bytes),或将字节流还原为Python对象。该过程主要依赖两大核心函数:pack负责序列化打包,unpack负责反序列化解包。

第1步:掌握基础打包语法与格式映射

struct.pack的标准调用格式为struct.pack(format, v1, v2, ...)。其中format是决定转换规则的格式字符串,v1至vN是需要转换的Python对象,返回值即为转换后的bytes实例。

>>> import struct
>>> struct.pack('i', 15)
b'\x0f\x00\x00\x00'
>>> struct.pack('iii', 15, 16, 17)
b'\x0f\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00'
>>> struct.pack('b', 255)   
struct.error: byte format requires -128 <= number <= 127
>>> struct.pack('B', 200)
b'\xc8'
>>> struct.pack('B', 71)
b'G'

上述示例中,i代表有符号整型(int),数字15被转换为占据4个字节的小端序字节串。当连续使用iii时,表示连续打包三个整数。b和B分别对应1字节有符号和无符号字符,当传入越界数值时会触发struct.error。

格式字符串中的字母严格对应底层存储结构,常用类型映射如下:

格式符C语言类型说明标准大小(字节)
b / Bsigned char / unsigned char有符号/无符号单字节1
h / Hshort / unsigned short有符号/无符号短整型2
i / Iint / unsigned int有符号/无符号常规整型4
l / Llong / unsigned long有符号/无符号长整型4
q / Qlong long / unsigned long long8字节整型8
n / Nssize_t / size_t系统指针长度整型变长
e-IEEE 754半精度浮点数2
ffloat4字节浮点数4
ddouble8字节双精度浮点数8
cchar长度为1的字节串动态
s / pchar[] / packed char[]字符串/帕斯卡字符串动态
?_Bool布尔值1
x-填充字节(不产生实际值)动态

第2步:配置字节序与对齐规则

不同架构CPU对多字节数据的存储顺序不同,struct支持通过格式字符串的首位字符指定编码时的字节序(Endianness)与内存对齐方式。默认情况下使用@,即采用本机的原生字节序与对齐规则。

>>> struct.pack(">i", 15)    
b'\x00\x00\x00\x0f'
>>> struct.pack("<i", 15)    
b'\x0f\x00\x00\x00'

常用的对齐前缀含义如下:

  • @:本机字节序,原样使用C结构体对齐规则。
  • =:本机字节序,但取消填充对齐(Packed size),相邻变量紧凑排列。
  • <:小端序(Little-endian),低地址存低位字节,常见于x86/x64架构。
  • >:大端序(Big-endian),低地址存高位字节。
  • !:网络字节序(等同大端序),适用于TCP/IP网络协议传输。

第3步:获取占用空间与执行缓冲流操作

在实际解析未知协议或分配内存缓冲区时,calcsize可直接根据格式串计算出打包后占用的确切字节数:

>>> struct.calcsize('B')
1
>>> struct.calcsize('i')
4
>>> struct.calcsize('III')
12

若需避免频繁创建临时字节串以提升内存效率,可使用pack_into与unpack_from直接读写预设的缓冲区(Buffer):

# 将数据写入 buffer 的 offset 偏移处
struct.pack_into(format, buffer, offset, v1, v2, ...)
# 从 buffer 的 offset 偏移处依次读取
struct.unpack_from(format, buffer, offset=0)

对于同一格式多次打包的场景,推荐实例化Struct类进行预编译,内部会自动缓存编译后的字节码与结构信息:

>>> s = struct.Struct("III")
>>> s.pack(1, 2, 3)
b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'
>>> s.size  
12

异常排查与注意事项

在使用struct模块时,最常见的运行时异常源于数据类型越界或格式串与实际数据量不匹配。例如使用'b'格式打包超出-128 ~ 127区间的整数会抛出struct.error。此外,unpack解包时必须保证传入的字节流长度严格等于calcsize计算的预期长度,否则同样会触发尺寸不匹配错误。

总结

通过掌握格式字符串的映射规则、灵活切换字节序前缀,并利用Struct类与缓冲函数优化读写性能,开发者即可在Python中稳健地完成各类定长二进制流的序列化与反序列化工作。以上就是Python struct模块进行二进制打包与解包的详细内容,更多关于Python基础编程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。