在使用 Python 做 Redis 开发时,发现 Python 自带的序列化都不太好用,对于复杂的数据结构的处理都不到位,经过领导推荐,开始使用 MessagePack 进行序列化编程。它是一个跨语言工具,支持十几种语言,在传输数据上号称比 JSON 更小更快。

本文以 Python 为例简单介绍

下载

1
$ pip install msgpack-python

Hello World

MessagePack 的序列化方法很简单 packb() ,反序列 unpackb()

1
2
3
4
5
6
7
In [1]: import msgpack

In [2]: msgpack.packb('Hello World') # 序列化
Out[2]: b'\xabHello World'

In [3]: msgpack.unpackb(msgpack.packb('Hello World')) # 反序列
Out[3]: b'Hello World'

反序列后输出结果依然是字节数组类型,这不是我们想要的,想要得到字符串类型,我们需要用到 encoding 参数

1
2
In [4]: msgpack.unpackb(msgpack.packb('Hello World'), encoding='utf-8')
Out[4]: 'Hello World'

JSON

1
2
In [10]: msgpack.unpackb(msgpack.packb({"name": "wxnacy"}), encoding='utf-8')
Out[10]: {'name': 'wxnacy'}

简单的 JSON 数据直接使用即可,但是如果 JSON 中的数据类型比较特殊,比如 datetime 就会有点麻烦

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: wxnacy([email protected])

import msgpack
from datetime import datetime

useful_dict = {
"id": 1,
"created": datetime.now(),
}
packed_dict = msgpack.packb(useful_dict)

1
TypeError: can't serialize datetime.datetime(2017, 12, 25, 21, 26, 48, 277551)

如上,直接进行序列化会报错,此时需要教给它怎么处理这种类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: wxnacy([email protected])

import msgpack
from datetime import datetime

useful_dict = {
"id": 1,
"created": datetime.now(),
}
def decode_datetime(obj):
if '__datetime__' in obj:
obj = datetime.strptime(obj["as_str"], "%Y%m%dT%H:%M:%S.%f")
return obj

def encode_datetime(obj):
if isinstance(obj, datetime):
return {'__datetime__': True, 'as_str': obj.strftime("%Y%m%dT%H:%M:%S.%f")}
return obj

packed_dict = msgpack.packb(useful_dict, default=encode_datetime)
this_dict_again = msgpack.unpackb(packed_dict, object_hook=decode_datetime,
encoding='utf-8')

通过 defaultobject_hook 分别制定序列和反序列的解析方法,通过上边这个例子,我们照葫芦画瓢把其他它不能识别的类都解析出来。

03-16 19:00