上一篇
Python struct模块使用教程 - 二进制数据处理指南
- Python
- 2025-08-19
- 1541
Python struct模块使用教程
掌握二进制数据处理的强大工具 - 打包、解包和字节顺序控制
1
struct模块简介
Python的struct
模块提供了在Python值和C结构体之间进行转换的功能。它用于处理存储在文件或网络连接中的二进制数据,特别适用于处理二进制文件格式、网络协议和与其他语言编写的程序交互。
使用struct
模块,您可以:
- 将Python数据打包成二进制格式
- 从二进制数据中解包出Python值
- 处理字节顺序(大端、小端)
- 计算二进制数据结构的大小
2
核心函数
pack(fmt, v1, v2, ...)
将Python值打包成二进制字符串(Python字节对象)。
import struct
# 打包一个整数和两个浮点数
packed_data = struct.pack('i f f', 42, 3.14, 2.718)
print(packed_data) # 输出:b'*\x00\x00\x00\xc3\xf5H@\xb6\xf3\x1d@'
unpack(fmt, buffer)
从二进制数据中解包出Python值。
# 解包之前打包的数据
unpacked_data = struct.unpack('i f f', packed_data)
print(unpacked_data) # 输出:(42, 3.140000104904175, 2.7179999351501465)
calcsize(fmt)
计算给定格式字符串对应的二进制数据大小(字节数)。
size = struct.calcsize('i f f')
print(f"结构体大小: {size} 字节") # 输出:结构体大小: 12 字节
3
格式字符串详解
格式字符串由两部分组成:字节顺序指示符和类型格式字符。
字节顺序、大小和对齐方式
字符 | 字节顺序 | 大小 | 对齐方式 |
---|---|---|---|
@ | 本机 | 本机 | 本机 |
= | 本机 | 标准 | 无 |
< | 小端 | 标准 | 无 |
> | 大端 | 标准 | 无 |
! | 网络(大端) | 标准 | 无 |
常用格式字符
格式 | C类型 | Python类型 | 大小(字节) |
---|---|---|---|
x | 填充字节 | 无 | 1 |
c | char | bytes(长度为1) | 1 |
b | signed char | 整数 | 1 |
B | unsigned char | 整数 | 1 |
? | _Bool | bool | 1 |
h | short | 整数 | 2 |
H | unsigned short | 整数 | 2 |
i | int | 整数 | 4 |
I | unsigned int | 整数 | 4 |
l | long | 整数 | 4 |
L | unsigned long | 整数 | 4 |
q | long long | 整数 | 8 |
Q | unsigned long long | 整数 | 8 |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | bytes | 长度指定 |
p | char[] | bytes | Pascal字符串 |
P | void * | 整数 | 指针大小 |
重要提示: 格式字符前面可以加数字表示重复次数,例如'4s'表示长度为4的字符串。字节顺序字符应放在格式字符串的开头。
4
实际应用示例
示例1:处理简单的数据结构
import struct
# 定义数据
data = (1, 2.5, b'OK')
# 打包数据 (小端顺序: 整数, 浮点数, 4字节字符串)
fmt = '< i f 4s'
packed = struct.pack(fmt, data[0], data[1], data[2])
# 解包数据
unpacked = struct.unpack(fmt, packed)
print(f"原始数据: {data}")
print(f"打包后: {packed}")
print(f"解包后: {unpacked}")
示例2:处理二进制文件头部
import struct
# 模拟一个PNG文件头
png_header = b'\x89PNG\r\n\x1a\n' + struct.pack('>II', 13, 0x49484452)
# 解析PNG文件头
signature = png_header[0:8]
chunk_length = struct.unpack('>I', png_header[8:12])[0]
chunk_type = png_header[12:16].decode('ascii')
print(f"签名: {signature}")
print(f"块长度: {chunk_length}")
print(f"块类型: {chunk_type}")
处理复杂数据结构
import struct
# 定义复杂数据结构
# 格式: 网络字节序, 无符号短整型, 双精度浮点数, 10字节字符串, 布尔值
fmt = '! H d 10s ?'
# 创建数据
values = (500, 3.1415926535, b'Python', True)
# 打包数据
packed_data = struct.pack(fmt, *values)
print(f"打包后的数据 ({len(packed_data)} 字节): {packed_data}")
# 解包数据
unpacked = struct.unpack(fmt, packed_data)
print(f"解包后的数据: {unpacked}")
5
使用注意事项
- 字节顺序:网络传输和跨平台应用应使用大端('!'或'>')或明确指定字节顺序
- 数据对齐:C结构体可能有填充字节,使用标准大小和本机顺序时需注意
- 字符串处理:'s'格式需要指定长度,打包时字符串会被截断或填充
- 大小端差异:不同架构处理器可能使用不同字节顺序
- 错误处理:数据长度不匹配会引发struct.error异常
- 浮点数精度:Python的float是双精度,但打包为单精度会损失精度
最佳实践: 对于跨平台应用,始终明确指定字节顺序(使用'<','>'或'!'),避免使用本机顺序('@')。在打包和解包前使用calcsize()验证数据大小。
6
实际应用场景
- 网络编程:打包/解包网络协议数据包
- 文件格式处理:读写二进制文件格式(如图像、音频、视频)
- 硬件交互:处理来自传感器和硬件的二进制数据
- 跨语言通信:与C/C++程序交换数据
- 数据序列化:自定义高效的二进制数据序列化格式
- 数据库存储:紧凑存储结构化数据
本文由YongZhe于2025-08-19发表在吾爱品聚,如有疑问,请联系我们。
本文链接:https://521pj.cn/20258502.html
发表评论