Skip to content

序列化/反序列化

JSON

JSON 是一种轻量级的数据交换格式

常用方法:

  • json.dump(): 将 python 数据对象以 JSON 格式数据流的形式写入文件
  • json.load(): 解析包含 JSON 数据的文件为 python 对象
  • json.dumps(): 将 python 数据对象转换为 JSON 格式的字符串
  • json.loads(): 将包含 JSON 的字符串、字节以及字节数据解析为 python 对象
JSON Python
object dict
array list tuple
string str
number(int) int
number(real) float
true True
false False
null None

反序列化

要将 JSON 数据的字符串转换为 python 的值,就将它传递给 json.loads() 函数(这个名字的意思是“load string”,而不是“loads”)

1
2
3
4
5
In [2]: string_of_json_data = '{"name": "Zophie", "isCat": true, "miceCaught": 0, "felineIQ": null}'
In [4]: import json
In [5]: string_python = json.loads(string_of_json_data)
In [6]: string_python
Out[6]: {'name': 'Zophie', 'isCat': True, 'miceCaught': 0, 'felineIQ': None}

导入 json 模块后,就可以调用 loads(),向它传入一个 JSON 数据字符串。请注意,JSON 字符串总是用双引号。它将返回一个 python 字典。python 字典是没有顺序的,所以打印的键值对可能以不同的顺序出现

1
2
3
4
In [8]: json_str = '[1, 2, 3]'
In [9]: python_str = json.loads(json_str)
In [10]: python_str
Out[10]: [1, 2, 3]

序列化

json.dumps() 函数(它表示“dump string”,而不是“dumps”)将一个 python 值转换成 JSON 格式的数据字符串

1
2
3
4
5
6
In [11]: python_val = {'name': 'Zophie', 'isCat': True, 'miceCaught': 0, 'felineIQ': None}
In [12]: json_str = json.dumps(python_val)
In [13]: json_str
Out[13]: '{"name": "Zophie", "isCat": true, "miceCaught": 0, "felineIQ": null}'
In [15]: print(type(json_str))
<class 'str'>

处理中文字符

注意:JSON 只理解 Unicode 字符串

1
2
3
4
In [16]: python_val = {'name': '不要香菜', 'isCat': True, 'miceCaught': 0, 'felineIQ': None}
In [17]: json_str = json.dumps(python_val)
In [18]: json_str
Out[18]: '{"name": "\\u4e0d\\u8981\\u9999\\u83dc", "isCat": true, "miceCaught": 0, "felineIQ": null}'

可以看到,中文字符都变成了 Unicode 字符

为了输出中文,还需要指定参数 ensure_ascii 为 False

1
2
3
In [20]: json_str = json.dumps(python_val, ensure_ascii=False)
In [21]: json_str
Out[21]: '{"name": "不要香菜", "isCat": true, "miceCaught": 0, "felineIQ": null}'

格式化输出:

1
2
with open("xxx.json", "w", encoding='utf-8') as f:
    f.write(json.dumps(res_l, ensure_ascii=False, indent=2))

demjson

https://github.com/dmeranda/demjson

1
2
3
4
5
import demjson
In [12]: demjson.encode( ['one',42,True,None] )
Out[12]: '["one",42,true,null]'
In [13]: demjson.decode( '["one",42,true,null]' )
Out[13]: ['one', 42, True, None]

demjson 可以处理一些非标准的 json 字符串

例如: 字典的字符串键值没有加双引号

1
2
3
4
5
6
7
In [14]: s = '{a: 1}'

In [15]: demjson.decode(s)
Out[15]: {'a': 1}

In [16]: json.loads(s)
JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

pickle

https://docs.python.org/zh-cn/3/library/pickle.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import pickle

with open("/Users/nocilantro/Downloads/data_20210208", "rb") as f:
  data = f.read()
  data = pickle.loads(data)
  print(data)

with open(CONTEXT_FILE_PATH, "rb") as f:
    data = pickle.load(f)
    print(data)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import pickle
import pandas as pd

dic = {
    1: 2,
    2: pd.DataFrame({1: [1, 2], "2": [2, 3]})
}
data = pickle.dumps(dic)
print(data)
print(type(data))


dic_load = pickle.loads(data)
print(dic_load)

存储到 redis:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import pickle
import pandas as pd
from redis import Redis

client = Redis()
dic = {
    1: 2,
    2: pd.DataFrame({1: [1, 2], "2": [2, 3]})
}
data = pickle.dumps(dic)
print(type(data))

client.set("pickle_key", data)

bytes_data = client.get("pickle_key")
dic_load = pickle.loads(bytes_data)
print(dic_load)