器→工具, 编程语言

Python标准库之结构体struct

钱魏Way · · 105 次浏览

Python struct简介

在C语言的学习中,我们接触到了结构体。Python 的 struct 模块用于在 Python 中处理 C 语言风格的结构化数据。它允许用户将 Python 中的数据打包成字节流,或者从字节流中解包数据,这对于文件读写、网络通信以及与其他编程语言的交互非常有用。

产生背景

  • 跨语言数据交换: 在许多应用中,Python 程序需要与其他使用不同语言(如 C 或 C++)编写的程序进行数据交换。由于不同语言的数据表示方式不同,需要一种通用的方式来表示和传输数据,struct 模块正是为此而生。
  • 字节序和数据对齐: 不同的计算机体系结构可能使用不同的字节序(大端或小端),并且数据对齐方式可能不同。struct 模块允许显式指定字节序和对齐方式,以确保在不同平台上数据的正确解析。
  • 高效的二进制数据处理: 在处理大型二进制文件或通过网络发送二进制数据时,需要一种高效的方法来打包和解包数据,而不是逐字节处理。

使用场景

  • 文件I/O: 读取和写入二进制文件,尤其是那些遵循特定结构或协议的文件格式。
  • 网络通信: 在通过套接字发送和接收数据时,通常需要以字节流的形式打包和解包数据。
  • 嵌入式系统: 在与硬件设备通信时,数据通常以二进制格式发送和接收。
  • 与C语言交互: 在需要与 C 语言编写的库或程序进行数据交换时,struct 模块可以帮助将数据格式化为 C 语言所需的格式。

Python struct使用

struct 模块提供了几个关键的函数:

  • pack(format, v1, v2, …):将Python值打包成二进制数据。
  • unpack(format, buffer):将二进制数据解包成Python值。
  • calcsize(format):计算格式字符串描述的结构的大小。

struct.pack(fmt, v1, v2, …)

将 Python 值 v1, v2, … 根据格式化字符串 fmt 打包成二进制数据。

  • fmt:格式化字符串,指定如何打包数据。
  • v1, v2, …:要打包的值。

格式化字符串的常用格式:

  • ‘b’:带符号字节(1 字节)
  • ‘B’:无符号字节(1 字节)
  • ‘h’:带符号短整数(2 字节)
  • ‘H’:无符号短整数(2 字节)
  • ‘i’:带符号整数(4 字节)
  • ‘I’:无符号整数(4 字节)
  • ‘f’:浮点数(4 字节)
  • ‘d’:双精度浮点数(8 字节)
  • ‘s’:字符串

示例:

import struct

# 打包数据
packed_data = struct.pack('iif', 1, 2, 3.14)
print(packed_data)  # 输出: b'\x01\x00\x00\x00\x02\x00\x00\x00\xcd\xcc\x0c@'

struct.unpack(fmt, buffer)

从 buffer 中解包数据,根据格式化字符串 fmt 返回一个元组。

  • fmt:格式化字符串,指定如何解包数据。
  • buffer:要解包的二进制数据。

示例:

import struct

# 打包数据
packed_data = struct.pack('iif', 1, 2, 3.14)

# 解包数据
unpacked_data = struct.unpack('iif', packed_data)
print(unpacked_data)  # 输出: (1, 2, 3.140000104904175)

struct.calcsize(fmt)

返回给定格式化字符串 fmt 所需的字节数。这对于确定数据结构的大小非常有用。

  • fmt:格式化字符串。

示例:

import struct

size = struct.calcsize('iif')
print(size)  # 输出: 12 (4 字节整数 + 4 字节整数 + 4 字节浮点数)

格式化字符串的语法

  • ‘<‘:小端字节序(Least significant byte first)
  • ‘>’:大端字节序(Most significant byte first)
  • ‘!’:网络字节序(Big-endian)

格式化字符的组合定义了数据的布局。例如,’iif’ 表示两个整数和一个浮点数,'<2if’ 表示一个小端字节序的整数、一个小端字节序的整数和一个小端字节序的浮点数。

完整示例

# 打包数据
data = struct.pack('!I4sh', 1024, b'test', 8)
print(data)  # 输出二进制数据

# 解包数据
unpacked_data = struct.unpack('!I4sh', data)
print(unpacked_data)  # 输出 (1024, b'test', 8)

在这个例子中,’!I4sh’ 是格式字符串,其中:

  • !表示网络字节序(大端)。
  • I表示一个无符号整型(4字节)。
  • 4s表示一个4字节的字符串。
  • h表示一个短整型(2字节)。

通过使用 struct 模块,Python 程序可以方便地在不同平台和语言之间传输和解析二进制数据。

参考链接:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注