当我们在内存中定义一个dict的时候,我们是可以随时修改变量的内容的:
>>> d=dict(name='wc',age=28) >>> d {'name': 'wc', 'age': 28}
我们可以随时修改name和age的值。但是当我们重新运行程序的时候,name、age的初始化值还是wc和28,实际情况下我们需要保存该dict的最后的值。
我们把变量从内存中变成可存储或传输的过程称之为序列化。python中称之为pickling,Java中叫serialization,都是一个意思。序列化之后我们就可以把内容写入到磁盘或者通过网络传输出去。反之,把变量从序列化的对象重新读取到内存中称之为反序列化,洋名叫unpickling。
python中实现序列化的模块叫pickle。pickle.dumps()方法可以把任意的对象序列化成一个Bytes,然后就可以把这个bytes写入文件。pickle.dump()方法可以直接把对象序列化写入一个file-like的对象中。相反的,pickle.loads()方法可以把文件中的内容读入到一个bytes,然后把这个bytes对象转换为目标类型对象,也可以使用pickle.load()方法直接从一个file-like对象中直接反序列化出对象:
>>> f = open('E:\python3.6.3\workspace\dump.txt','wb') >>> pickle.dump(d,f) >>> f.close() >>> f=open('E:\python3.6.3\workspace\dump.txt','rb') >>> c = pickle.load(f) >>> c {'name': 'wc', 'age': 28}
JSON
实际开发中我们或多或少都会碰到跨语言传输数据的问题,这就要求我们要把对象序列化为标准格式,比如JSON和XML。JSON的表现形式就是一个字符串,可以被所有的语言读取。可以方便的存储到磁盘或者通过网络传输。JSON表示的对象是标准的JavaScript的对象,其和python内置的数据类型的对应关系如下:
JSON类型 | Python类型 |
{} | dict |
[] | list |
"" | str |
123.4 | int 或 float |
true/false | True/False |
null | None |
python内置了json模块可以方便的在python对象和json对象之间转换:
>>> import json >>> d=dict(name='wc',age=28) >>> json.dumps(d) '{"name": "wc", "age": 28}' >>> c = json.dumps(d) >>> d=json .loads(c) >>> d {'name': 'wc', 'age': 28}
python内置的数据类型可以直接转换为json类型,但是class对象并不刻意直接转为json,这是因为class对象默认的并不具有可序列化的属性。
2种方法,第一种是通过dumps()方法的default参数,把任意一个对象转换为一个可序列化的对象。下面的例子中,先定义一个Student的class,然后定义一个student2dict()函数,该函数的作用就是把Student的属性转换为dict,最后再序列化为json:
>>> import json >>> class Student(object): ... def __init__(self,name,age): ... self.name = name ... self.age = age ... >>> def student2dict(s): ... return {'name':s.name,'age':s.age} ... >>> s=Student('wc',28) >>> print(json.dumps(s,default=student2dict)) {"name": "wc", "age": 28}
第二种方法,借用class对象的__dict__属性:
>>> class Teacher(object): ... def __init__(self,name,age): ... self.name = name ... self.age = age ... >>> t = Teacher('ly',90) >>> print(json.dumps(t,default=lambda obj:obj.__dict__)) {"name": "ly", "age": 90}