您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > Python处理JSON
概念序列化(Serialization):将对象的状态信息转换为可以存储或可以通过网络传输的过程,传输的格式可以是JSON、XML等。反序列化就是从存储区域(JSON,XML)读取反序列化对象的状态,重新创建该对象。JSON(JavaScriptObjectNotation):一种轻量级数据交换格式,相对于XML而言更简单,也易于阅读和编写,机器也方便解析和生成,Json是JavaScript中的一个子集。Python2.6开始加入了JSON模块,无需另外下载,Python的Json模块序列化与反序列化的过程分别是encoding和decodingencoding:把一个Python对象编码转换成Json字符串decoding:把Json格式字符串解码转换成Python对象对于简单数据类型(string、unicode、int、float、list、tuple、dict),可以直接处理。json.dumps方法对简单数据类型encoding:importjsondata=[{'a':A,'b':(2,4),'c':3.0}]#list对象printDATA:,repr(data)data_string=json.dumps(data)printJSON:,data_string输出:DATA:[{'a':'A','c':3.0,'b':(2,4)}]#python的dict类型的数据是没有顺序存储的JSON:[{a:A,c:3.0,b:[2,4]}]JSON的输出结果与DATA很相似,除了一些微妙的变化,如python的元组类型变成了Json的数组,Python到Json的编码转换规则是:json.loads方法处理简单数据类型的decoding(解码)转换importjsondata=[{'a':A,'b':(2,4),'c':3.0}]#list对象data_string=json.dumps(data)printENCODED:,data_stringdecoded=json.loads(data_string)printDECODED:,decodedprintORIGINAL:,type(data[0]['b'])printDECODED:,type(decoded[0]['b'])输出:ENCODED:[{a:A,c:3.0,b:[2,4]}]DECODED:[{u'a':u'A',u'c':3.0,u'b':[2,4]}]ORIGINAL:type'tuple'DECODED:type'list'解码过程中,json的数组最终转换成了python的list,而不是最初的tuple类型,Json到Python的解码规则是:json的人文关怀编码后的json格式字符串紧凑的输出,而且也没有顺序,因此dumps方法提供了一些可选的参数,让输出的格式提高可读性,如sort_keys是告诉编码器按照字典排序(a到z)输出。importjsondata=[{'a':'A','b':(2,4),'c':3.0}]print'DATA:',repr(data)unsorted=json.dumps(data)print'JSON:',json.dumps(data)print'SORT:',json.dumps(data,sort_keys=True)输出:DATA:[{'a':'A','c':3.0,'b':(2,4)}]JSON:[{a:A,c:3.0,b:[2,4]}]SORT:[{a:A,b:[2,4],c:3.0}indent参数根据数据格式缩进显示,读起来更加清晰:importjsondata=[{'a':'A','b':(2,4),'c':3.0}]print'DATA:',repr(data)print'NORMAL:',json.dumps(data,sort_keys=True)print'INDENT:',json.dumps(data,sort_keys=True,indent=2)输出:DATA:[{'a':'A','c':3.0,'b':(2,4)}]NORMAL:[{a:A,b:[2,4],c:3.0}]INDENT:[{a:A,b:[2,4],c:3.0}]separators参数的作用是去掉,,:后面的空格,从上面的输出结果都能看到,:后面都有个空格,这都是为了美化输出结果的作用,但是在我们传输数据的过程中,越精简越好,冗余的东西全部去掉,因此就可以加上separators参数:importjsondata=[{'a':'A','b':(2,4),'c':3.0}]print'DATA:',repr(data)print'repr(data):',len(repr(data))print'dumps(data):',len(json.dumps(data))print'dumps(data,indent=2):',len(json.dumps(data,indent=2))print'dumps(data,separators):',len(json.dumps(data,separators=(',',':')))输出:DATA:[{'a':'A','c':3.0,'b':(2,4)}]repr(data):35dumps(data):35dumps(data,indent=2):76dumps(data,separators):29skipkeys参数,在encoding过程中,dict对象的key只可以是string对象,如果是其他类型,那么在编码过程中就会抛出ValueError的异常。skipkeys可以跳过那些非string对象当作key的处理.importjsondata=[{'a':'A','b':(2,4),'c':3.0,('d',):'Dtuple'}]try:printjson.dumps(data)except(TypeError,ValueError)aserr:print'ERROR:',errprintprintjson.dumps(data,skipkeys=True)输出:ERROR:keysmustbeastring[{a:A,c:3.0,b:[2,4]}]让json支持自定义数据类型以上例子都是基于python的built-in类型的,对于自定义类型的数据结构,json模块默认是没法处理的,会抛出异常:TypeErrorxxisnotJSONserializable,此时你需要自定义一个转换函数:importjsonclassMyObj(object):def__init__(self,s):self.s=sdef__repr__(self):return'MyObj(%s)'%self.sobj=.MyObj('helloworld')try:printjson.dumps(obj)exceptTypeError,err:print'ERROR:',err#转换函数defconvert_to_builtin_type(obj):print'default(',repr(obj),')'#把MyObj对象转换成dict类型的对象d={'__class__':obj.__class__.__name__,'__module__':obj.__module__,}d.update(obj.__dict__)returndprintjson.dumps(obj,default=convert_to_builtin_type)输出:ERROR:MyObj(helloworld)isnotJSONserializabledefault(MyObj(helloworld)){s:hellworld,__module__:MyObj,__class__:__main__}#注意:这里的class和module根据你代码的所在文件位置不同而不同相反,如果要把jsondecode成python对象,同样也需要自定转换函数,传递给json.loads方法的object_hook参数:#jsontest.pyimportjsonclassMyObj(object):def__init__(self,s):self.s=sdef__repr__(self):returnMyObj(%s)%self.sdefdict_to_object(d):if'__class__'ind:class_name=d.pop('__class__')module_name=d.pop('__module__')module=__import__(module_name)printMODULE:,moduleclass_=getattr(module,class_name)printCLASS,class_args=dict((key.encode('ascii'),value)forkey,valueind.items())print'INSTANCEARGS:',argsinst=class_(**args)else:inst=dreturninstencoded_object='[{s:helloworld,__module__:jsontest,__class__:MyObj}]'myobj_instance=json.loads(encoded_object,object_hook=dict_to_object)printmyobj_instance输出:MODULE:module'jsontest'from'E:\Users\liuzhijun\workspace\python\jsontest.py'CLASSclass'jsontest.MyObj'INSTANCEARGS:{'s':u'helloworld'}[MyObj(helloworld)]MODULE:module'jsontest'from'E:\Users\liuzhijun\workspace\python\jsontest.py'CLASSclass'jsontest.MyObj'INSTANCEARGS:{'s':u'helloworld'}[MyObj(helloworld)]使用Encoder与Decoder类实现json编码的转换JSONEncoder有一个迭代接口iterencode(data),返回一系列编码的数据,他的好处是可以方便的把逐个数据写到文件或网络流中,而不需要一次性就把数据读入内存.importjsonencoder=json.JSONEncoder()data=[{'a':'A','b':(2,4),'c':3.0}]forpartinencoder.iterencode(data):print'PART:',part输出:PART:[PART:{PART:aPART::PART:APART:,PART:cPART::PART:3.0PART:,PART:bPART::PART:[2PART:,4PART:]PART:}PART:]encode方法等价于''.join(encoder.iterencode(),而且预先会做些错误检查(比如非字符串作为dict的key),对于自定义的对象,我们只需从些JSONEncoder的default()方法,其实现方式与上面提及的函数convet_to_builtin_type()是类似的。importjsonimportjson_myobjclassMyObj(object):def__init__(self,s):self.s=sdef__repr__(self):returnMyObj(%s)%self.sclassMyEncoder(json.JSONEncoder):defdefault(self,obj):print'default(',repr(obj),')'#Co
本文标题:Python处理JSON
链接地址:https://www.777doc.com/doc-4355044 .html