序列化是指把内存里的数据转变成字符串,以使其能保存到硬盘上或者通过网络输送到远程。
序列化的两个模块:
json:只能把python中的int/str/list/tuple/dict类型的数据,可以在不同的语言之间传递数据。Python和JavaScript数据对应关系:
JavaScript | Python |
{ } | dict |
[] | list |
"String" | str |
12345.6 | int/float |
true/false | True/False |
null | None |
pickle:支持所有的python数据,但是只能在python中使用,存储数据占空间大。
python 的 json库:常用的方法有json.dumps()、json.loads()、json.dump、json.load()
Json
json.dumps():
-
import json
-
dic = { "name": "egon", "password": "abc123"}
-
print(dic)
-
print(json.dumps(dic))
输出的结果
-
{ 'name': 'egon', 'password': 'abc123'}
-
{ "name": "egon", "password": "abc123"}
对比dict类型数据和json类型数据可以知道在json中字符串符号都是用双引号,而在python中一般字符串是用单引号,在打印输出上有一些区别。dic是dict类型,json.dumps(dic)是str类型。
josn.loads():
-
import json
-
dic = { "name": "egon", "password": "abc123"}
-
json_data = json.dumps(dic)
-
str_dic1 = '{"name": "egon", "password": "abc123"}'
-
print(json.loads(json_data))
-
print(json.loads(str_dic1))
输出的结果
-
< class 'dict'>
-
{ 'name': 'egon', 'password': 'abc123'}
-
< class 'dict'>
-
{ 'name': 'egon', 'password': 'abc123'}
根据输出结果可以看出,json.loads()可以把json.dumps()转换的json数据再还原,也可以把字符串中符合json格式的数据还原成dict类型。
json.dump():
-
import json
-
dic = { "name": "egon", "password": "abc123"}
-
file = open( 'info.json', 'w')
-
json.dump(dic, file)
这段代码运行后会生成一个info.json文件,json.dump()就是把数据dic转成json数据,然后存入info.json中。
当然也可以用with语句
-
import json
-
dic = { "name": "egon", "password": "abc123"}
-
with open('info.json', 'w') as file:
-
json.dump(dic, file)
两种方式保存的文件内容一致:
{"name": "egon", "password": "abc123"}
json.load():
-
import json
-
dic = { "name": "egon", "password": "abc123"}
-
with open('info.json', 'r') as file:
-
data = json.load(file)
-
print(type(data))
-
print(data)
输出的结果
-
< class 'dict'>
-
{'name': 'egon', 'password': 'abc123'}
json.load()把文件中json格式的字符串还原成字典
关于json的高级用法
一般json不能直接转换自定义的对象,可以定义一个函数用于将对象转换成字典,来实现将自定义对象转换为json数据
定义一个student类,并创建一个对象s
-
class student:
-
def __init__(self, name, age):
-
self.name = name
-
self.age = age
-
def tostr(self):
-
print(self.name, self.age)
-
s = student( 'bighead', 22)
直接调用json.dumps(s),会报错,因为json.dumps()无法直接转换自定义对象
但是查看json.dumps()函数会发现有很多参数
其中有一个default的参数
定义一个把student对象转换成字典的方法
-
def student_to_dict(s):
-
return {'name': s.name, 'age': s.age}
然后调用json.dumps()
-
data = json.dumps(s, default=student_to_dict)
-
print(data)
输出的结果
{"name": "bighead", "age": 22}
会发现能使用json序列化自定义对象了
但是还可以用另一种不定义函数的方式序列化自定义对象,因为通常每个自定义对象都有一个.__dict__属性
-
data = json.dumps(s, default= lambda obj:obj.__dict__)
-
print(data)
输出的结果
{"name": "bighead", "age": 22}
但是这样只能把自定义对象转为json,还不能把json数据还原为自定义对象
查看json.loads()函数的全部参数会发现有一个参数object_hook
定义一个函数把字典转换成student对象
-
def dict_to_student(dic):
-
return student(dic['name'], dic['age'])
然后调用json.loads()
-
s = json.loads(data, object_hook=dict_to_student)
-
print(type(s))
-
s.tostr()
输出的结果
-
< class '__main__.student'>
-
bighead 22
原本的json数据被转换成了student对象
相同的,json.dump()也能使用default参数,json.load()也能使用object_hook参数
Pickle
pickle.dumps():
这个函数会把python所有的类型的数据转换成二进制数据,所以在把用pickle转换后的数据存进文件时,要使用'wb'的方式,打开文件
-
import pickle
-
dic = { 'name': 'egon', 'password': 'abc123'}
-
data = pickle.dumps(dic)
-
print(data)
运行的结果
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00egonq\x02X\x08\x00\x00\x00passwordq\x03X\x06\x00\x00\x00abc123q\x04u.'
可以看到,pickle.dumps()可以把字典类型的数据转换成二进制数据
相同的pickle.dump(),也可以把python的数据转换成二进制数据,但是这个方法可以直接将数据存入指定文件
-
import pickle
-
dic = { 'name': 'egon', 'password': 'abc123'}
-
with open('pickle', 'wb')as f:
-
pickle.dump(dic, f)
pickle.loads():
与pickle.dumps()功能相反,这个函数是把pickle.dumps()序列化后的数据还原
-
dic1 = pickle.loads(data)
-
print(dic1)
运行的结果
{'name': 'egon', 'password': 'abc123'}
相同的,pickle.load()方法也能将序列化的数据还原,但是pickle.load()需要打开存储序列化数据的文件
-
with open('pickle', 'rb')as f:
-
dic2 = pickle.load(f)
-
print(dic2)
运行的结果
{'name': 'egon', 'password': 'abc123'}