在进行数据传递(如网络通讯时),就需要对数据做序列化与反序列化;对于json类型可方便地通过json模块处理;但对于C语言的struct数据,则需要使用struct模块。
struct模块
通过struct模块,可打包与解包C结构体数据。使用时需要导入struct库:
import struct
函数
函数 | 返回 | 说明 |
---|---|---|
pack(fmt, v1, v2, …) | bytes | 按照给定的格式(fmt),把数据转换成字节流 |
pack_into(fmt,buffer,offset,v1,v2…) | None | 按照给定的格式(fmt),将数据转换成字节流,并写入以offset开始的buffer中 |
unpack(fmt, buffer) | tuple | 按照给定的格式(fmt)解析字节流,并返回解析结果; 字节流的长度必须与calcsize(fmt)相等 |
pack_from(fmt,buffer,offset) | tuple | 按照给定的格式(fmt)解析字节流(从offset开始),并返回解析结果 |
calcsize(fmt) | Integer | 计算给定的格式(fmt)占用多少字节 |
格式化
打包与解包时,需要指定数据格式(包括长度)。
对齐方式
结构体需要设定对齐方式与大小端。
Character | Byte order | Size and alignment |
---|---|---|
@ | native(本机) | native 凑够4个字节 |
= | native(本机) | standard 按原字节数 |
< | little-endian(小端) | standard 按原字节数 |
> | big-endian(大端) | standard 按原字节数 |
! | network (= big-endian) | standard 按原字节数 |
格式符
通过格式符,指定具体的格式化方式。
Format | C Type | Python | 字节数 |
---|---|---|---|
x | pad byte | no value | |
c | char | bytes of length 1 | 1 |
b | signed char | integer | 1 |
B | unsigned char | integer | 1 |
? | _Bool /bool(C++) | 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[] | bytes | |
p | char[] | bytes | |
P | void * | integer |
注:
- 每个格式前可以有一个数字;表示这个类型的个数,如:
- s只格式化一个字节;对于字符串,需要先通过encode编码:
'我的'.encode('utf-8')
- 4s格式化四个字节;
- 4i表示四个int;
- s只格式化一个字节;对于字符串,需要先通过encode编码:
- q和Q只适用于64位机器;
- P用来转换一个指针,其长度和计算机相关。
json模块
json用于编码、解码JSON对象,使用时需要导入:
import json
函数
函数 | 描述 |
---|---|
json.dumps(obj) | 将 Python 对象编码成 JSON 字符串 |
json.loads(s) | 将已编码的 JSON (str、bytes或bytearray)解码为 Python 对象 |
类型映射
python 原始类型向 json 类型的转化对照表:
Python | JSON |
---|---|
dict | object (key总是编码为字符串) |
list, tuple | array |
str, unicode | string |
int, long, float | number |
True | true |
False | false |
None | null |
json 类型转换到 python 的类型对照表:
JSON | Python |
---|---|
object | dict |
array | list |
string | unicode |
number (int) | int, long |
number (real) | float |
true | True |
false | False |
null | None |
示例
纯struct结构体
struct{
int cmd;
bool busy;
}
格式化一个cmd=10,busy=true的命令:
buffer = struct.pack('=ib', 10, 1)
# 或
buffer = struct.pack('=i?', 10, True)
结构体后跟字符串(json格式)
struct{
int cmd;
}
// 后跟数组json
格式化一个cmd=-5,json为{“result”:0, “msg”:“OK”}的命令:
buffer = struct.pack('=i', -5) + json.dumps({"result":0, "msg":"OK"}).encode('utf-8')
反序列化(以接收到上面序列化后buffer为例):
cmd = struct.unpack('=i',buffer[:4])
resp = json.loads(buffer[4:])
result = resp['result']