在Python和C结构之间转换的函数,用于二进制数据存储和处理,处理c语言中的结构体。
常用函数
常用函数包括如下三个,pack将数据封装成字节流;unpack根据给定格式解析字节,返回tuple类型; calcsize返回给定的格式占用内存的字节数。
struct.pack(fmt, v1, v2, ...) -> bytes
struct.unpack(fmt, buffer) -> (v1, v2, ...)
struct.calcsize(fmt) -> int
格式符(fmt)
格式符用来表示字节封装或解析的格式,注意:
1.每个格式符前可以有一个数字,表示个数,比如4s表示长度为4的字符串,2i表示两个整数;
2.q和Q只在机器支持64位操作时有意义;
3.P用来转换一个指针,其长度和计算机相关;
4.f和d的长度和计算机相关。
格式符 | C语言类型 | Python类型 | 内存大小 |
---|---|---|---|
x | 填充字节 | 无 | 1 |
c | char | string(长度为1) | 1 |
b | signed char | int | 1 |
B | unsigned char | int | 1 |
h | short | int | 2 |
H | unsigned short | int | 2 |
i | int | int | 4 |
I | unsigned int/long | int/long | 4 |
L | unsigned long | long | 8 |
q | long long | long | 8 |
Q | unsigned long long | long | 8 |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | string | 1 |
p | char[] | string | 1 |
? | _Bool | bool | 1 |
对齐方式
字符 | 字节顺序 | 大小 |
---|---|---|
@(默认) | 与本机一致 | 凑够4个字节 |
= | 与本机一致 | 按原字节数 |
< | 小端 | 按原字节数 |
> | 大端 | 按原字节数 |
! | network(大端) | 按原字节数 |
示例
pack
*注意:*python3所有字符串都是 unicode 字符串,若直接用pack封装会报如下错误:
#error: argument for 's' must be a bytes object
因此字符串处理前需要使用’utf-8’编码,具体方法如下代码段。
import struct
a=10
b='apple'
c=35.9
d=True
data=struct.pack("i5sf?",a,b.encode('utf-8'),c,d)#对字符串先编码
print(data)
#输出:b'\n\x00\x00\x00apple\x00\x00\x00\x9a\x99\x0fB\x01'
unpack
import struct
t=struct.unpack("i5sf?",data)
#或者:t1,t2,t3,t4=struct.unpack("i5sf?",data)
print(t)
#输出:(10, b'apple', 35.900001525878906, True)
calcsize
import struct
struct.calcsize('5s')
#输出:5
struct.calcsize('3if')
#输出:16
#16=3*4+4
struct.calcsize('i5sf?')
#输出:17
#17=4+5+3+4+1
'''
注意:其中3表示填充,因为默认对齐方式为@
字节字符串s可以以任何偏移量开头,因为其标准大小为1;
i,f等只能以4的倍数的偏移量开头。例如0、4、8等;
L,d等只能以8的倍数的偏移量开头。例如0、8、16等。
'''
struct.calcsize('=i5sf?')
#输出:14
#14=4+5+4+1 按原字节数