序列化:把变量从内存中变成可存储或传输的过程。
Python中内置了pickle模块来实现序列化。
import pickle
d = dict(name='Bob', age=18)
# dumps()把任意对象序列化成一个bytes
print(pickle.dumps(d))
# 把对象序列化后直接写入文件中
with open('F:/dump.txt', 'wb') as f:
pickle.dump(d, f)
# 从文件中读取内容
with open("F:/dump.txt", 'rb') as f:
print(pickle.load(f))
pickle模块来实现序列化是Python独有的特性。如果要跨语言传递数据,就需要采用标准的格式,比如XML、json。采用json更方便快捷。
Python内置了json模块。
import json
# 序列化成json字符串
d1 = dict(name='ABC', age=20)
print(json.dumps(d1))
print(json.loads(json.dumps(d1)))
with open('F:/json.txt', 'w') as f:
json.dump(d1, f)
with open('F:/json.txt', 'r') as f:
print(json.load(f))
一般更多的,我们要对class进行序列化,可以定义一个defalut方法。看下面代码:
class People:
# __slots__ = ('name', 'age')
def __init__(self, name, age):
self.name = name
self.age = age
def people2dict(p):
return {
'name': p.name,
'age': p.age
}
p = People('无敌', 18)
print(json.dumps(p, default=people2dict))
通常class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量,也有例外,比如定义了__slots__的class就没有__dict__属性。
所以上述序列化代码可以简写为:
print(json.dumps(p, default=lambda obj: obj.__dict__, ensure_ascii=False, indent=2, sort_keys=True))
其中参数ensure_ascii=False才输出中文,否则输出Unicode编码。
indent=2格式化json,大小代表缩进间隔。
如果要把json反序列化为对象呢?需要定义object_hook函数。
def dict2people(d):
return People(d['name'], d['age'])
# 把json反序列化成对象
print(json.loads(json.dumps(p, default=people2dict), object_hook=dict2people))