# 这是学习廖雪峰老师python教程的学习笔记
1、概览
在程序运行的过程中,所有的变量都是在内存中。但是一旦程序结束,变量所占用的内存就被操作系统全部回收。而如果要保存变量的修改,我们就可以用序列化。
我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling。
序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上
反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
2、pickle模块
Python提供了pickle模块来实现序列化 和 反序列化
1、序列化
d = dict(name='Bob', age=20, score=88) # 定义一个字典
# pickle.dumps()——将对象序列化为bytes,并打印出来,需要手动写入文件
>>> import pickle # 导入pickle模块
>>> pickle.dumps(d) # 将对象序列化成一个bytes
b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.'
# pickle.dump()——将序列化的信息直接写入file-like Object,不打印
>>> f = open('dump.txt', 'wb') # 创建文件对象
>>> pickle.dump(d, f) # 将d序列化,二进制格式写入f
>>> f.close() # 关闭文件对象
2、反序列化
# pickle.loads()——根据生成的bytes 反序列化
x=b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.' #将序列化出的bytes 赋值给 x
>>> pickle.loads(x) # 反序列化
{'age': 20, 'score': 88, 'name': 'Bob'}
# pickle.load()——读取file-like Object 的数据 反序列化
>>> f = open('dump.txt', 'rb') #创建可读文件对象。格式为二进制
>>> d = pickle.load(f) # 从f 中读取数据,反序列化
>>> f.close()
>>> d
{'age': 20, 'score': 88, 'name': 'Bob'}
3、注意
反序列化出的变量和原来的变量是完全不相干的对象,它们只是内容相同而已。
Pickle只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据
3、JSON的序列化
如果要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式。而JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。
Python对象到JSON格式的转换需要json模块,它调用的方法同pickle模块类似。
d = dict(name='Bob', age=20, score=88)
1、序列化
# json.dumps()——序列化并打印
>>> import json
>>> json.dumps(d)
'{"age": 20, "score": 88, "name": "Bob"}'
# json.dump——直接把JSON写入一个file-like Object
2、反序列化
# json.loads()——把JSON的字符串反序列化
>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'
>>> json.loads(json_str)
{'age': 20, 'score': 88, 'name': 'Bob'}
# json.load()——从file-like Object中读取字符串并反序列化
3、class序列化为JSON
1、序列化
import json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
s = Student('Bob', 20, 88)
print(json.dumps(s))
如果我们直接将Student的实例序列化为JSON,则会报错。这是因为默认情况下,dumps()方法不知道如何将Student的实例变为一个JSON的{}对象。
而可选参数default可以把任意一个对象变成一个 可序列为 JSON的对象,我们只需要为Student专门写一个转换函数,再把函数传进去即可。
def student2dict(std):
return {
'name': std.name,
'age': std.age,
'score': std.score
}
Student实例首先被student2dict()函数转换成一个可序列为JSON的dict对象,然后再被顺利序列化为JSON
>>> print(json.dumps(s, default=student2dict))
{"age": 20, "name": "Bob", "score": 88}
编写专门的函数序列化,太过麻烦。更简洁的方法如下:
# 把任意class的实例变为dict
# 将实例s,传给 obj 参数,然后返回 obj.__dict__就是个dict
print(json.dumps(s, default=lambda obj: obj.__dict__))
通常class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量
>>> s.__dict__
{'name': 'Bob', 'age': 20, 'score': 88}
>>> type(s.__dict__)
<class 'dict'>
2、反序列化
loads()方法首先转换出一个dict对象,然后,我们传入的object_hook函数负责把dict转换为Student实例
# dict 转换为Student() 的函数
def dict2student(d):
return Student(d['name'], d['age'], d['score'])
>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}' # 需要反序列化的json字符串
>>> print(json.loads(json_str, object_hook=dict2student)) 将json_str通过dict2student 转化为Student()
<__main__.Student object at 0x10cd3c190>
原文地址:http://blog.51cto.com/12758568/2116906