当前位置:首页 > Python > 正文

Python struct模块使用教程 - 二进制数据处理指南

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
ccharbytes(长度为1)1
bsigned char整数1
Bunsigned char整数1
?_Boolbool1
hshort整数2
Hunsigned short整数2
iint整数4
Iunsigned int整数4
llong整数4
Lunsigned long整数4
qlong long整数8
Qunsigned long long整数8
ffloatfloat4
ddoublefloat8
schar[]bytes长度指定
pchar[]bytesPascal字符串
Pvoid *整数指针大小
重要提示: 格式字符前面可以加数字表示重复次数,例如'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++程序交换数据
  • 数据序列化:自定义高效的二进制数据序列化格式
  • 数据库存储:紧凑存储结构化数据

发表评论