📜  Python中的struct模块(1)

📅  最后修改于: 2023-12-03 14:46:38.990000             🧑  作者: Mango

Python中的struct模块介绍

在Python中,有一个非常实用的模块叫作struct,它能够让我们方便地处理二进制数据。如果你需要读取或者生成二进制数据,那么就可以用到该模块。在这里我们将为大家介绍一下该模块的基本使用和一些常见应用。

基础用法

使用struct模块需要先导入包:

import struct

对于一个二进制数据,我们需要先定义它的格式,然后再进行处理。下面是一些常用的格式:

| 字符 | 对应数据类型 | | ---- | ----------- | | b | 带符号字节 | | B | 无符号字节 | | h | 带符号短整数 | | H | 无符号短整数 | | i | 带符号整数 | | I | 无符号整数 | | q | 带符号长整数 | | Q | 无符号长整数 | | f | 单精度浮点数 | | d | 双精度浮点数 |

接下来,我们需要使用pack函数来将数据按格式打包成二进制数据:

data = struct.pack('i', 10)

这个函数的第一个参数是格式字符串,意思是对应的数据类型。第二个参数是对应的数据。上面的代码将整数10按照i格式打包成了二进制流。

我们也可以使用unpack函数将一个已经打包的二进制流解包成对应的数据:

num = struct.unpack('i', data)[0]

该函数的第一个参数同样是格式字符串,第二个参数则是需要解包的二进制流,函数会返回一个元组,我们可以通过下标来获取对应的值,比如上面的例子中就是第一个元素。

常见应用
处理网络数据

在网络通信中,经常需要处理各种类型的数据流。使用struct模块可以方便地将数据打包成网络字节序(network byte order),也可以将网络字节序的数据解包成本机字节序(host byte order),进而进行操作。

import socket
import struct

def pack_short(short):
    # 打包短整数(2字节)成网络字节序
    return struct.pack('!H', short)

def unpack_short(short_bytes):
    # 将网络字节序的短整数解包成本机字节序
    return struct.unpack('!H', short_bytes)[0]

def send_short(sock, short):
    # 发送短整数给socket
    sock.send(pack_short(short))

def recv_short(sock):
    # 接收socket中的短整数
    short_bytes = sock.recv(2)
    return unpack_short(short_bytes)

上面是一个处理短整数的例子,包含了打包成网络字节序、解包成本机字节序、发送给socket和从socket接收等操作。

解析图片文件

对于一些二进制格式的文件(如图片、视频等),使用struct模块可以对它们进行解析和读取,进而获取其中的数据。下面是一个读取BMP图片文件中像素数据的例子。

BMP图片格式是简单的二进制格式,由一个位图文件头和一个位图信息头组成,我们可以根据这些信息来读取图片像素数据。

import struct

with open('image.bmp', 'rb') as f:
    # 读取位图文件头
    bmp_header = f.read(14)
    if bmp_header[0:2] != b'BM':
        raise Exception('Not a BMP file')
    # 读取位图信息头
    bmp_info_header = f.read(40)
    width, height, _, _, _, _, _, _, _, _ = struct.unpack('<iiiiiiiiii', bmp_info_header)
    # 检查是否为24位真彩色图像
    if struct.unpack('<h', bmp_info_header[14:16])[0] != 24:
        raise Exception('Not a 24-bit true-color BMP file')
    # 读取像素数据
    f.seek(struct.unpack('<i', bmp_header[10:14])[0])
    pixel_data = f.read(width * height * 3)

上面的代码中,我们根据BMP文件格式中的位图文件头和位图信息头来读取文件信息和像素数据,并进行一些基本的检查。由于BMP是小端字节序(little-endian)的格式,因此需要使用<进行对应的解析。

结论

struct模块是Python中非常实用的一个库,它可以帮助我们方便地处理二进制数据。如果你需要进行二进制数据的读取、生成或者传输等操作,那么就一定要使用这个模块。