python模块整理13-json模版

时间:2021-02-25 15:49:41

参考
Json概述以及python对json的相关操作
http://www.cnblogs.com/coser/archive/2011/12/14/2287739.html
http://blog.csdn.net/toontong/article/details/4979572
一、json模版介绍
python中的json解释库有好几个,其中不同版本有使用上的差异。
常用有 json-py 与smiplejson 两个包
其中json-py 包含一个minjson,用法一样,只是import时 是 import minjson
两个用法上有差别, 但import语句一样,
import json # 都是如此import的。
import minjson
# json-py库用法
json.read( js_obj )
json.write(py_obj)
#json的minjson用法
minjson.read( js_obj )
minjson.write(py_obj)
# smiplejson 的用法
json.loads(js_obj)
json.dumps(py_obj)

python2.5没有内置的json,
python2.6内置json解释库,是 smiplejson
smiplejson 下载 http://pypi.python.org/pypi/simplejson/
json-py 下载 http://sourceforge.net/projects/json-py/files/

二、使用smiplejson json
1、简单使用
>>> import json
>>> obj = [[1,2,3],123,123.123,'abc',{'key1':(1,2,3),'key2':(4,5,6)}]
>>> encodedjson = json.dumps(obj)
>>> print repr(obj)
[[1, 2, 3], 123, 123.123, 'abc', {'key2': (4, 5, 6), 'key1': (1, 2, 3)}]
>>> print encodedjson
[[1, 2, 3], 123, 123.123, "abc", {"key2": [4, 5, 6], "key1": [1, 2, 3]}]
>>>
通过输出的结果可以看出,简单类型通过encode之后跟其原始的repr()输出结果非常相似,但是有些数据类型进行了改变,
例如上例中的元组则转换为了列表。在json的编码过程中,会存在从python原始类型向json类型的转化过程,具体的转化
可help(json)
2、json.dumps方法
比较常用的有sort_keys(对dict对象进行排序,我们知道默认dict是无序存放的),separators,indent等参数。
data1 = {'b':789,'c':456,'a':123}
d1 = json.dumps(data1,sort_keys=True)
indent参数是缩进的意思,它可以使得数据存储的格式变得更加优雅。
data1 = {'b':789,'c':456,'a':123}
d1 = json.dumps(data1,sort_keys=True,indent=4)
print d1
输出:
{
"a": 123,
"b": 789,
"c": 456
}
json主要是作为一种数据通信的格式存在的,而网络通信是很在乎数据的大小的,无用的空格会占据很多通信带宽,所以适当时候也要对数据进行压缩。
separator参数可以起到这样的作用,该参数传递是一个元组,包含分割对象的字符串
json.dumps(data1, separators=(',',':')

三、处理自己的数据类型
方法一:自己写转化函数
1、数据转换方式说明
json.dumps()方法里的default(obj)
``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError.
一个函数返回一个序列化的对象[这个函数将dumps第一个参数(对象)解析后返回字典]
json.loads()方法里的object_hook
``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``).
The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders
(e.g. JSON-RPC class hinting).
“对象钩”“是一个可选的功能,将调用可选的函数将一个字典解码成对象.
对象钩子(函数)的返回值(一个json对象)将替换字典,可以使用此功能来实现自定义的解码器

实质就是自定义object类型和dict类型进行转化。object2dict函数将对象模块名、类名以及__dict__存储在dict对象里,并返回。
dict2object函数则是反解出模块名、类名、参数,创建新的对象并返回。
在json.dumps方法中增加default参数,该参数表示在转化过程中调用指定的函数,同样在decode过程中json.loads方法增加object_hook,指定转化函数。
2、事例
'''
Created on 2012-10-26

@author: Jin
'''
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __repr__(self):
return 'Person Object name : %s,age:%d' % (self.name,self.age)

if __name__ == '__main__':
P = Person('jin',22)
print P

'''
Created on 2012-10-26

@author: Jin
'''
# -*- coding: utf-8 -*-

import jsont
import json

p = jsont.Person('Jin',22)

def object2dict(obj):
'''convert object to a dic'''
d = {}
d['__class__'] = obj.__class__.__name__
d['__module__'] = obj.__module__
d.update(obj.__dict__)
return d

def dict2object(d):
''' convert dict to object'''
if '__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
module = __import__(module_name)
class_ = getattr(module,class_name)
args = dict((key.encode('ascii'),value) for key,value in d.items()) #get args
inst =class_(**args) #create new instance
else:
inst =d
return inst

d = object2dict(p)
print d
#{'age': 22, '__module__': 'jsont', '__class__': 'Person', 'name': 'Jin'}

o = dict2object(d)
print type(o),o
#<class 'jsont.Person'> Person Object name : Jin,age:22

dump = json.dumps(p, default=object2dict)# Understand don't get it
print dump,'test'
#{"age": 22, "__module__": "jsont", "__class__": "Person", "name": "Jin"}

load = json.loads(dump,object_hook = dict2object)
print load
#Person Object name : Jin,age:22

方法二:继承JSONEncoder和JSONDecoder类,覆写相关方法
JSONEncoder类负责编码,主要是通过其default函数进行转化,我们可以override该方法。同理对于JSONDecoder。
json.JSONEncoder 对象转换为字典
json.JSONDecoder 字典转换为一个json对象

'''
Created on 2012-10-26

@author: json
'''
import jsont
import json

p = jsont.Person('jin',22)

class MyEncoder(json.JSONEncoder):
'''
classdocs
'''
def default(self,obj):
#convert object to a dict
d = {}
d['__class__'] = obj.__class__.__name__
d['__module__'] = obj.__module__
d.update(obj.__dict__)
return d
class MyDecoder(json.JSONDecoder):
def __init__(self):
json.JSONDecoder.__init__(self,object_hook=self.dict2object)
def dict2object(self,d):
#convert dict to object
if'__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
module = __import__(module_name)
class_ = getattr(module,class_name)
args = dict((key.encode('ascii'), value) for key, value in d.items()) #get args
inst = class_(**args) #create new instance
else:
inst = d
return inst

d = MyEncoder().encode(p)
o = MyDecoder().decode(d)

print d
print type(o),o

结果
{"age": 22, "__module__": "jsont", "__class__": "Person", "name": "jin"}
<class 'jsont.Person'> Person Object name : jin,age:22