Python struct模块解析

  • Post category:Python

Python struct模块是一个Python标准库,用于将Python数据类型转换为C结构体形式的字节流,并将字节流转换回Python数据类型。本文将对这个模块进行详细介绍,并提供两个使用示例。

struct模块的基本用法

struct模块主要由pack()和unpack()两个函数组成,它们可以将字符串和Python数据类型相互转换。

pack()

pack()函数将Python数据类型转换为C结构体形式的字节流。它的语法如下:

struct.pack(format, v1, v2, ...)
  • format:字符串,表示按照何种格式转换。
  • v1, v2, …:Python数据类型,需要转换的值。格式的个数应该和值的数量相同。

下表是格式符和转换类型的对应关系:

格式符 C类型 Python类型
x pad byte no value
c char bytes of length 1
b signed char integer
B unsigned char integer
? _Bool bool
h short integer
H unsigned short integer
i int integer
I unsigned int integer or long
l long integer
L unsigned long integer or long
q long long(skill) integer
Q unsigned long long(skill) integer or long
f float float
d double float
s char[] string
p char[] string
P void* long

以下是一个使用pack()函数的示例,将一个字符串和一个整数转换为字节流:

import struct

s = struct.pack('3s2i', b'abc', 1, 2)
print(s)

输出结果:

b'abc\x01\x00\x00\x00\x02\x00\x00\x00'

unpack()

unpack()函数将C结构体形式的字节流转换为Python数据类型。它的语法如下:

struct.unpack(format, buffer)
  • format:字符串,表示按照何种格式转换。
  • buffer:字节流数据。

下面是一个使用unpack()函数的示例,将一个字节流转换为字符串和整数:

import struct

s = b'abc\x01\x00\x00\x00\x02\x00\x00\x00'
t = struct.unpack('3s2i', s)
print(t)

输出结果:

(b'abc', 1, 2)

示例一:将图片文件转换为字节流

下面是一个将图片文件转换为字节流的示例:

import struct

# 读取文件
with open('lena.bmp', 'rb') as f:
    s = f.read()

# 将长度和文件内容打包为字节流
bs = struct.pack('i{}s'.format(len(s)), len(s), s)

# 将字节流写入文件
with open('lena.bin', 'wb') as f:
    f.write(bs)

注意,这里使用了'i{}s'.format(len(s))动态生成了格式字符串。使用这种方式可以在保证代码简洁同时,使得格式字符串更加灵活。

示例二:将字节流转换为自定义类型

下面是一个将字节流转换为自定义类型的示例:

import struct

class Student:
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score

    def pack(self):
        return struct.pack('20sii', self.name.encode(), self.age, self.score)

    @staticmethod
    def unpack(bs):
        name, age, score = struct.unpack('20sii', bs)
        return Student(name.strip().decode(), age, score)

# 创建一个学生对象,并将其打包为字节流
stu = Student('Tom', 20, 90)
bs = stu.pack()

# 将字节流转换回学生对象
stu2 = Student.unpack(bs)

# 检验结果
print(stu2.name, stu2.age, stu2.score)

输出结果:

Tom 20 90

在这个示例中,我们自定义了一个Student类,并实现了打包和解包方法,将其转换为字节流。这个示例也展示了如何使用类的静态方法从字节流中解析出对象。