struct 模块详解

python中struct 模块用于python数据结构与C结构之间的相互转换,其中C结构是用一种格式化字符串表示的,学习struct 模块的难点就在这个格式化字符串上,强烈建议最好了解下C语言结构体的相关知识点,如果比较熟悉C语言结构体及对齐,学习struct 模块轻而易举。
官方英文文档:struct — Interpret strings as packed binary data¶

struct 模块方法

#将v1 v2按照fmt 转化为一个字节流(bytes)
struct.pack(fmt, v1, v2, ...)
#将v1 v2按照fmt 转化为一个字节流(bytes),并写入buffer,从位置offset处开始写入
struct.pack_into(fmt, buffer, offset, v1, v2, ...)
#将字节流按照fmt转化为python对象返回
struct.unpack(fmt, string)
#同unpack,只是针特定buffer转化为python对象返回
struct.unpack_from(fmt, buffer[, offset=0])
#返回fmt的所表示的C结构体所占字节大小
struct.calcsize(fmt)
#如果一述函数使用过程中fmt格式不对,会抛出这个异常
exception struct.error

格式化串

格式化串的字符根据功能不同可以分为两类,一类用于控制字节顺序、大小及对齐(Byte Order, Size, and Alignment),另一类用于表示结构体的组成(Format Characters)。

Byte Order, Size, and Alignment

字节顺序对齐相关知识详见C语言字节对齐问题详解(对齐、字节序、网络序等)

字符 字节序 大小 对齐方式
@ 原生 原生 原生
= 原生 标准
< 小端 标准
> 大端 标准
! 网络字节序 标准

注:原生指使用本地机器的字节序、大小和对齐方式
这些字符出现在格式化字符串的开头,如果没有给出,默认为@,字节大小一列中的标准是指下面的Format Characters。

Format Characters

字符 C Type Python type Standard size
x pad byte no value
c char string of length 1 1
b signed char integer 1
B unsigned char integer 1
? _Bool bool 1
h short integer 2
H unsigned short integer 2
i int integer 4
I unsigned int integer 4
l long integer 4
L unsigned long integer 4
q long long integer 8
Q unsigned long long integer 8
f float float 4
d double float 8
s char[] string
p char[] string
P void * integer

一个栗子

下面通过一个简单的例子说明 struct模块的使用

import struct
str = struct.pack('=H4sII', 0x04, b'aaaa', 0x01, 0x0e)
a, b, c, d = struct.unpack('=H4sll', str)
print("a={0},b={1},c={2},d={3}.".format(a, b, c, d))
print(struct.calcsize('=H4sII'))

运行结果

a=4,b=b'aaaa',c=1,d=14.
14

格式化字串’=H4sII’所表示的C结构体写成C语言如下:

struct H4sII
{
    unsigned short a;
    char        b[4]; 
    unsigned int   c;
    unsigned int   d;
}

=表示使用本机字节序、标准大小、无对齐
H表示unsigned short 占2个字节大小
4s 一个长度为4的字符数组占4个字节大小
I表示unsigned int 占4个字大小
由于没有对齐,故格式化字串’=H4sII’表示的结构体大小为2+4+4+4=14
如果去掉=号,会怎么样呢?

import struct

str = struct.pack('H4sII', 0x04, b'aaaa', 0x01, 0x0e)
a, b, c, d = struct.unpack('H4sll', str)
print("a={0},b={1},c={2},d={3}.".format(a, b, c, d))
print(struct.calcsize('H4sII'))

运行结果

a=4,b=b'aaaa',c=1,d=14.
16

如果pack与unpack的时候使用的格式化串不一致,会抛出异常 struct.error

import struct

str = struct.pack('=H4sII', 0x04, b'aaaa', 0x01, 0x0e)
a, b, c, d = struct.unpack('H4sll', str)
print("a={0},b={1},c={2},d={3}.".format(a, b, c, d))

运行结果

Traceback (most recent call last):
  File "D:/home/test1.py", line 4, in 
    a, b, c, d = struct.unpack('H4sll', str)
struct.error: unpack requires a bytes object of length 16

你可能感兴趣的:(python)