python 序列化与反序列化

参考: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 :
     import cPickle as pickle;
except ImportError:
     import pickle;
 
# 此处定义一个dict字典对象
d = dict (name = 'Zhangsan' , age = 23 , score = 80 );
str = pickle.dumps(d); # 调用pickle的dumps函数进行序列化处理
print str ;
 
# 定义和创建一个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 :
     import cPickle as pickle;
except ImportError:
     import pickle;
 
# 从之前序列化的dump.txt文件里边读取内容
f = open ( 'dump.txt' , 'rb' ); # 设定文件选项模式为rb
d = pickle.load(f); # 调用load做反序列处理过程
f.close(); # 关闭文件资源
print d;
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
 
import json;
 
# 定义dict字典对象
d1 = dict (name = 'zhangsan' , age = 20 , score = 80 );
str = json.dumps(d1); # 调用json的dumps函数进行json序列化处理
print str ;
 
# 调用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
 
import json;
 
# 定义person类
class Person( object ):
     # person类的构造函数__init__
     def __init__( self , name, age):
         self .name = name;
         self .age = age;
     
     # 获取name属性函数
     def getName( self ):
         return self .name;
     
     # 获取age属性函数
     def getAge( self ):
         return self .age;
 
# 定义并实例化person类对象
# 设定实际参数分别为:name=zhangsan,age=23
p = Person( 'zhangsan' , 23 );
print p;
 
print json.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, in dumps
     return _default_encoder.encode(obj)
   File "/usr/lib64/python2.6/json/encoder.py" , line 367, in encode
     chunks = list(self.iterencode(o))
   File "/usr/lib64/python2.6/json/encoder.py" , line 317, in _iterencode
     for chunk in self._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, in default
     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
 
import json;
 
# 定义person类
class Person( object ):
     # person类的构造函数__init__
     def __init__( self , name, age):
         self .name = name;
         self .age = age;
     
     # 获取name属性函数
     def getName( self ):
         return self .name;
     
     # 获取age属性函数
     def getAge( self ):
         return self .age;
 
# 定义一个转换函数,此处其实就是告知json映射对应关系
def person2dict(person):
     return {
         'name'  :   person.name,
         'age'   :   person.age
     };
 
# 定义并实例化person类对象
# 设定实际参数分别为:name=zhangsan,age=23
p = Person( 'zhangsan' , 23 );
print p;
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做演示处理
class Student(Person):
     def __init__( self , name ,age, score):
         # Person.__init__(name, age); # 此处缺少了self参数
         Person.__init__( self , name, age);
         self .score = score;
     
     def getName( self ):
         # return Person.getName();
         return Person.getName( self );
     
     def getAge( self ):
         # return Person.getAge();
         return Person.getAge( self );
     
     def getScore( self ):
         return self .score;
 
s = Student( 'lisi' , 24 , 89 );
print s;
print 's.getName()=' , s.getName();
print 's.getAge()=' , s.getAge();
print 's.getScore()=' , s.getScore();
print (json.dumps(s, default = lambda obj:obj.__dict__));
print 'json student对象序列化成功。' ;
 
print '==========================演示json反序列化过程' ;
 
# 定义反序列化函数从dict转换到student对象
def dict2student(d):
     return Student(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);
print result;
print s = = 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值