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类,并实现了打包和解包方法,将其转换为字节流。这个示例也展示了如何使用类的静态方法从字节流中解析出对象。