在 Python 编程中,处理二进制数据是一项常见且重要的任务,尤其是在网络编程、文件操作等场景中。Python 的 struct
模块提供了强大的功能,能够将 Python 的数据类型与二进制数据进行相互转换,即把数据打包成二进制字节串,也能从二进制字节串中解析出数据。本文将详细介绍 struct
模块的使用方法、格式字符的含义以及实际应用场景,帮助你全面掌握这一模块。
struct
模块主要用于处理二进制数据的打包(将 Python 数据类型转换为二进制字节串)和解包(从二进制字节串中提取 Python 数据类型)。这在与底层系统交互、处理网络协议数据、读写二进制文件等场景中非常有用。
struct.pack(format, v1, v2, ...)
:根据指定的格式字符串 format
,将一系列 Python 值 v1, v2, ...
打包成一个二进制字节串。struct.unpack(format, buffer)
:根据指定的格式字符串 format
,从二进制字节串 buffer
中解包出一系列 Python 值。struct.calcsize(format)
:返回指定格式字符串 format
所对应的二进制数据的字节大小。格式字符 | C 类型 | Python 类型 | 字节数 |
---|---|---|---|
x |
填充字节 | 无 | 1 |
c |
char |
长度为 1 的字节串 | 1 |
b |
signed char |
整数 | 1 |
B |
unsigned char |
整数 | 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 |
浮点数 | 4 |
d |
double |
浮点数 | 8 |
s |
char[] |
字节串 | 指定长度 |
p |
char[] |
字节串 | 指定长度 |
在处理多字节数据时,需要考虑字节序(大端或小端)。struct
模块提供了以下字节序指示符:
符号 | 字节序 | 说明 |
---|---|---|
@ |
本机字节序 | 按照本机的字节序和对齐方式处理 |
= |
标准字节序 | 按照标准的字节序(通常是小端),不进行对齐 |
< |
小端字节序 | 低位字节在前 |
> |
大端字节序 | 高位字节在前 |
! |
网络字节序 | 等同于大端字节序,常用于网络编程 |
import struct
# 打包一个整数和一个浮点数
data = struct.pack('if', 10, 3.14)
print(data) # 输出打包后的二进制字节串
在这个示例中,'if'
是格式字符串,表示先打包一个整数(i
),再打包一个浮点数(f
)。
import struct
# 打包数据
packed_data = struct.pack('if', 10, 3.14)
# 解包数据
unpacked_data = struct.unpack('if', packed_data)
print(unpacked_data) # 输出解包后的 Python 元组
这里使用相同的格式字符串 'if'
对之前打包的二进制字节串进行解包,得到一个包含整数和浮点数的元组。
import struct
# 以大端字节序打包一个整数
big_endian_data = struct.pack('>i', 12345)
print(big_endian_data)
# 以小端字节序打包同一个整数
little_endian_data = struct.pack(', 12345)
print(little_endian_data)
在这个示例中,通过 >
和 <
分别指定大端和小端字节序进行数据打包。
在网络编程中,数据通常以二进制形式传输。使用 struct
模块可以将 Python 数据类型打包成二进制字节串发送,也能从接收到的二进制数据中解包出 Python 数据。例如,在一个简单的 TCP 服务器和客户端程序中:
# 服务器端
import socket
import struct
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8888))
server_socket.listen(1)
conn, addr = server_socket.accept()
data = conn.recv(1024)
unpacked_data = struct.unpack('if', data)
print(unpacked_data)
conn.close()
# 客户端
import socket
import struct
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 8888))
packed_data = struct.pack('if', 10, 3.14)
client_socket.sendall(packed_data)
client_socket.close()
在读写二进制文件时,struct
模块可以帮助我们准确地处理文件中的数据。例如,读取一个包含整数和浮点数的二进制文件:
import struct
# 写入二进制文件
with open('data.bin', 'wb') as f:
packed_data = struct.pack('if', 10, 3.14)
f.write(packed_data)
# 读取二进制文件
with open('data.bin', 'rb') as f:
data = f.read()
unpacked_data = struct.unpack('if', data)
print(unpacked_data)
struct
模块是 Python 中处理二进制数据的重要工具,通过格式字符串和核心函数,能够方便地实现 Python 数据类型与二进制数据的相互转换。在网络编程、二进制文件读写等场景中,struct
模块发挥着关键作用。掌握 struct
模块的使用,有助于你更好地处理底层的二进制数据。
Tekin的Python编程秘籍库: Python 实用知识与技巧分享,涵盖基础、爬虫、数据分析等干货 本 Python 专栏聚焦实用知识,深入剖析基础语法、数据结构。分享爬虫、数据分析等热门领域实战技巧,辅以代码示例。无论新手入门还是进阶提升,都能在此收获满满干货,快速掌握 Python 编程精髓。
Python 官方文档 - struct:https://docs.python.org/3/library/struct.html
介绍:Python 官方提供的关于 struct
模块的详细文档,包含了模块的所有功能、格式字符的详细说明和丰富的示例代码,是学习 struct
模块的权威资料。
《Python 核心编程》
介绍:这本书对 Python 的各个方面进行了深入讲解,其中包括 struct
模块的使用。书中的示例和讲解有助于读者更好地理解和应用该模块。
Stack Overflow:https://stackoverflow.com/
介绍:一个知名的编程问答社区,在上面可以搜索到很多关于 struct
模块的实际应用问题和解决方案,还能与其他开发者交流经验。