python中的struct主要是用来处理C结构数据的,比如存取二进制文件,socket操作。
struct模块中最重要的三个函数是pack(), unpack(), calcsize()
pack(fmt, v1, v2, ...) 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)
unpack(fmt, string) 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
calcsize(fmt) 计算给定的格式(fmt)占用多少字节的内存
格式符(fmt):
Format | C Type | Python | 字节数 |
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 or long | 4 |
l | long | integer | 4 |
L | unsigned long | long | 4 |
q | long long | long | 8 |
Q | unsigned long long | long | 8 |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | string | |
p | char[] | string | |
P | void * | long | |
注1:q和Q只适用于64位机器
注2:每个格式前可以有一个数字,表示个数。如:s格式表示一定长度的字符串,4s表示长度为4的字符串
注3:P用来转换一个指针,其长度和机器字长相关
对齐方式
为了同c中的结构体交换数据,还要考虑c或c++编译器使用了字节对齐,通常是以4个字节为单位的32位系统,故而struct根据本地机器字节顺序转换.可以用格式中的第一个字符来改变对齐方式.定义如下
CHARACTER | BYTE ORDER | SIZE | ALIGNMENT |
@ | native | native | native |
= | native | standard | none |
< | little-endian | standard | none |
> | big-endian | standard | none |
! | network (= big-endian) | standard | none |
< :Little-Endian就是低位字节排放在内存的低地址端(栈顶)。
> :Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
!:网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。
代码示例:
import struct
# native byteorder
buffer = struct.pack("ihb", 1, 2, 3)
print(repr(buffer))
print(struct.unpack("ihb", buffer))
# data from a sequence, network byteorder
data = [1, 2, 3]
buffer = struct.pack("!ihb", *data)
print(repr(buffer))
print(struct.unpack("!ihb", buffer))
# Output:
# '\x01\x00\x00\x00\x02\x00\x03'
# (1, 2, 3)
# '\x00\x00\x00\x01\x00\x02\x03'
# (1, 2, 3)