python 序列化与反序列化

来源:互联网 发布:淘宝客服的工作怎么样 编辑:程序博客网 时间:2024/04/28 22:09

参考:http://www.huxiusong.com/?p=297

本文目录为:
1、什么是序列化
2、Python序列化过程
3、Python反序列化过程
4、Python json序列化和反序列

全文内容为:
1、什么是序列化
程序运行的过程中,所有变量都是在内存中操作的,当程序一旦执行完毕,结束退出后,变量占有的内存就被操作系统回收了。
因此我们需要将某些数据持久化存储到磁盘中,下次运行的时候从磁盘中读取相关数据。

我们将变量从内存中变成可以存储或传输的过程称之为序列化,在Python中叫做pickling,在其它语言中也称之为
serialization、marshaling、flattening等等,说的都是一个意思。
反之,则为反序列化,称之为unpickling,把变量内容从序列化的对象重新读取到内存中。

2、Python序列化过程

0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Filename : pickling.py
 
# 尝试优先导入cPickle假定失败,再import导入pickle
try:
    importcPickle as pickle;
exceptImportError:
    importpickle;
 
# 此处定义一个dict字典对象
d=dict(name='Zhangsan', age=23, score=80);
str= pickle.dumps(d); # 调用pickle的dumps函数进行序列化处理
printstr;
 
# 定义和创建一个file文件对象,设定模式为wb
f=open('dump.txt','wb');
# 将内容序列化写入到file文件中
pickle.dump(d, f);
f.close();# 最后关闭掉文件资源
 
print'Done';

3、Python反序列化过程

0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Filename : unpickling.py
 
# 尝试优先导入cPickle假定失败,再import导入pickle
try:
    importcPickle as pickle;
exceptImportError:
    importpickle;
 
# 从之前序列化的dump.txt文件里边读取内容
f=open('dump.txt','rb');# 设定文件选项模式为rb
d=pickle.load(f); # 调用load做反序列处理过程
f.close();# 关闭文件资源
printd;
print'name is %s' % d['name'];
 
print'Done';

4、Python json序列化和反序列
此处先简单梳理下JSON类型和Python类型对照关系为:

0001
0002
0003
0004
0005
0006
0007
JSON类型  Python类型
{}      dict
[]      list
"string"   'str'或者u'unicode'
1234.56     int或float
true/false True/False
null        None

接着讲解Python的JSON序列化和反序列化过程为:

0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Filename : json_demo.py
 
importjson;
 
# 定义dict字典对象
d1=dict(name='zhangsan', age=20, score=80);
str= json.dumps(d1); # 调用json的dumps函数进行json序列化处理
printstr;
 
# 调用json的loads函数进行反序列化处理
d2=json.loads(str);
print'd1=', d1;
print'd2=', d2;
print'd1.name=', d1['name'];
print'd2.name=', d2['name'];
print'Done';

最后,我们讲解下常见的class对象的json序列化和反序列化过程。

0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Filename : json_obj.py
 
importjson;
 
# 定义person类
classPerson(object):
    # person类的构造函数__init__
    def__init__(self, name, age):
        self.name=name;
        self.age=age;
     
    # 获取name属性函数
    defgetName(self):
        returnself.name;
     
    # 获取age属性函数
    defgetAge(self):
        returnself.age;
 
# 定义并实例化person类对象
# 设定实际参数分别为:name=zhangsan,age=23
p=Person('zhangsan',23);
printp;
 
printjson.dumps(p);
print'Done';

以上代码执行后,出现问题为:

0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
<__main__.Person object at 0x1115f10>
Traceback (most recent call last):
  File"json_obj.py", line 27, in<module>
    print json.dumps(p);
  File"/usr/lib64/python2.6/json/__init__.py", line 230, indumps
    return_default_encoder.encode(obj)
  File"/usr/lib64/python2.6/json/encoder.py", line 367, inencode
    chunks = list(self.iterencode(o))
  File"/usr/lib64/python2.6/json/encoder.py", line 317, in_iterencode
    forchunk inself._iterencode_default(o, markers):
  File"/usr/lib64/python2.6/json/encoder.py", line 323, in_iterencode_default
    newobj = self.default(o)
  File"/usr/lib64/python2.6/json/encoder.py", line 344, indefault
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <__main__.Person object at 0x1115f10> is not JSON serializable

提示is not JSON serializable错误信息,处理办法为:

0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Filename : json_obj.py
 
importjson;
 
# 定义person类
classPerson(object):
    # person类的构造函数__init__
    def__init__(self, name, age):
        self.name=name;
        self.age=age;
     
    # 获取name属性函数
    defgetName(self):
        returnself.name;
     
    # 获取age属性函数
    defgetAge(self):
        returnself.age;
 
# 定义一个转换函数,此处其实就是告知json映射对应关系
defperson2dict(person):
    return{
        'name' :   person.name,
        'age'  :   person.age
    };
 
# 定义并实例化person类对象
# 设定实际参数分别为:name=zhangsan,age=23
p=Person('zhangsan',23);
printp;
print'p.getName()=', p.getName();
print'p.getAge()=', p.getAge();
 
# 此处必须要传递参数给dumps函数,否则将抛出TypeError错误
# print json.dumps(p);
print(json.dumps(p, default=person2dict));
print'person对象序列化完成。';
 
# 此处我们可以使用obj.__dict__属性处理
# 定义Student做演示处理
classStudent(Person):
    def__init__(self, name ,age, score):
        # Person.__init__(name, age); # 此处缺少了self参数
        Person.__init__(self, name, age);
        self.score=score;
     
    defgetName(self):
        # return Person.getName();
        returnPerson.getName(self);
     
    defgetAge(self):
        # return Person.getAge();
        returnPerson.getAge(self);
     
    defgetScore(self):
        returnself.score;
 
s=Student('lisi',24,89);
prints;
print's.getName()=', s.getName();
print's.getAge()=', s.getAge();
print's.getScore()=', s.getScore();
print(json.dumps(s, default=lambdaobj:obj.__dict__));
print'json student对象序列化成功。';
 
print'==========================演示json反序列化过程';
 
# 定义反序列化函数从dict转换到student对象
defdict2student(d):
    returnStudent(d['name'], d['age'], d['score']);
 
# 借助json的loads函数处理,传入dict2student object_hook函数
json_str='{"age": 23, "score": 89, "name": "张三"}';
result=json.loads(json_str, object_hook=dict2student);
printresult;
prints ==result;
print'result.getName()=', result.getName();
print'result.getAge()=', result.getAge();
print'result.getScore()=', result.getScore();
print'json反序列化成功。';

小结为:
Python序列化和反序列化用到了pickle和json,建议使用json,因为更加通用、简洁。
json模块的dumps()和loads()函数是定义得非常好的接口。

0 0
原创粉丝点击