如何用Python处理二进制数据?

来源:站长平台作者:俊华头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何用Python处理二进制数据?》,敬请观看详情。直接读写字节流时,字节序不对会让解析结果完全错乱。Python标准库里的struct模块能把字节和Python值互相转换,避免手动移位算偏移。本文说明如何用bytes、bytearray配合struct的pack和unpack处理整数、浮点及字符串,并对比手动解析的易错点。掌握对齐方式、格式字符与大小端标记,才能在网络协议和文件格式解析中稳定提取字段,减少隐蔽的数据错误。

在系统编程、网络协议解析以及文件格式处理中,经常会遇到需要直接操作字节的情况。Python提供了内置的字节类型以及标准库模块,可以让开发者以可控的方式读写二进制数据,而不必关心底层内存布局的细节。

如何用Python处理二进制数据?

字节类型基础

Python中与二进制数据相关的核心类型是bytesbytearray。前者是不可变字节序列,适合表示固定的数据块;后者是可变字节序列,适合在解析过程中逐步修改内容。两者都支持索引和切片,但索引返回的是整数而非字符。

例如,构造一个包含三个字节的对象可以使用字面量或调用构造函数。字节值范围必须是0到255之间的整数,否则会抛出错误。理解这一点对于后续使用struct模块非常重要,因为所有打包操作最终都会生成符合该范围的字节序列。

# 不可变字节对象
b = bytes([0x01, 0x02, 0x03])
print(b[0])  # 输出 1

# 可变字节数组
ba = bytearray(b)
ba[0] = 0xFF
print(ba)  # 输出 bytearray(b'xffx02x03')

使用struct模块打包与解包

struct模块是解决二进制处理问题的关键工具。它定义了格式字符串,用来描述数据在字节中的排列方式。通过pack函数可以把Python值转换为字节,通过unpack可以把字节还原为Python值。格式字符包括整数、浮点、字符等类型,并可用前缀指定字节序和对齐方式。

如果不指定字节序,默认使用本机顺序和本机对齐,这在跨平台时容易出问题。通常建议显式使用<表示小端、>表示大端。下面的例子展示如何把一个无符号短整数和浮点数以小端方式写入字节,再读取出来。

import struct

# 小端格式:H表示无符号短整数,f表示浮点数
fmt = '<Hf'
data = struct.pack(fmt, 1024, 3.14)
print(data)  # 输出对应字节

# 解包还原
num, val = struct.unpack(fmt, data)
print(num, val)

处理字符串与定长字段

二进制协议中的文本常以固定长度存储,不足部分用空字节填充。struct支持用s加数字表示定长字节串,例如10s代表长度为10的字节串。注意它不会自动编码字符串,需要手动用encodedecode转换。

下面示例将一个名字写入并读出。若原始字符串超过长度会被截断,不足则用空字节补齐,读取后需去除多余空字符以保证内容正确。

import struct

name = 'alice'.encode('utf-8')
fmt = '<10s'
packed = struct.pack(fmt, name)
print(packed)

# 解包并去除空字节
raw = struct.unpack(fmt, packed)[0]
print(raw.rstrip(b'x00').decode('utf-8'))

手动解析的误区与对比

有些开发者倾向于用移位和按位与来提取字段,这种方法在简单场景下可行,但面对嵌套结构、不同字节序时会迅速变得难以维护。比如用(b[0] << 8) | b[1]解析大端短整数,若实际数据是小端就会得到错误结果。

使用struct不仅减少代码量,也把字节序和类型长度集中声明在格式串中,降低出错概率。在性能敏感场合,可配合struct.Struct缓存格式对象来减少重复解析开销,这是手动移位难以直观实现的优化。

import struct

# 缓存格式对象提升重复调用效率
parser = struct.Struct('<IH')
binary = parser.pack(1, 2)
a, b = parser.unpack(binary)
print(a, b)

实际应用场景建议

在处理自定义网络报文或解析旧版文件格式时,先画字段布局表,再用struct格式串一一映射,能显著提升代码可读性。对于变长内容,通常把长度字段放在头部,先读长度再读数据体,避免一次性读取造成阻塞或越界。

当数据量极大时,可结合memoryview避免复制字节,再用struct对切片解包,既节省内存又保持清晰逻辑。掌握这些组合用法,Python处理二进制数据就能做到既稳妥又高效。

import struct
from io import BytesIO

buf = BytesIO()
buf.write(struct.pack('<I', 3))
for i in range(3):
    buf.write(struct.pack('<H', i * 10))

buf.seek(4)
for _ in range(3):
    print(struct.unpack('<H', buf.read(2))[0])

Python二进制数据struct模块修改时间:2026-08-01 13:48:31

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。