参考:

概念

序列化(Serialization):将对象的状态信息转换为可以存储或可以通过网络传输的过程,传输的格式可以是JSON、XML等。反序列化就是从存储区域(JSON,XML)读取反序列化对象的状态,重新创建该对象。

JSON(JavaScript Object Notation):一种轻量级数据交换格式,相对于XML而言更简单,也易于阅读和编写,机器也方便解析和生成,Json是JavaScript中的一个子集。

Python2.6开始加入了JSON模块,无需另外下载,Python的Json模块序列化与反序列化的过程分别是 encoding和 decoding

encoding:把一个Python对象编码转换成Json字符串
decoding:把Json格式字符串解码转换成Python对象
对于简单数据类型(string、unicode、int、float、list、tuple、dict),可以直接处理。

json.dumps方法对简单数据类型encoding:
import json
data = [{'a':"A",'b':(2,4),'c':3.0}] #list对象
print "DATA:",repr(data) data_string = json.dumps(data)
print "JSON:",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(解码)转换
import json
data = [{'a':"A",'b':(2,4),'c':3.0}] #list对象 data_string = json.dumps(data)
print "ENCODED:",data_string decoded = json.loads(data_string)
print "DECODED:",decoded print "ORIGINAL:",type(data[0]['b'])
print "DECODED:",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)输出。

import json

data = [ { '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参数根据数据格式缩进显示,读起来更加清晰:

import json

data = [ { '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参数:

import json

data = [ { '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) : 35
dumps(data) : 35
dumps(data, indent=2) : 76
dumps(data, separators): 29

skipkeys参数,在encoding过程中,dict对象的key只可以是string对象,如果是其他类型,那么在编码过程中就会抛出ValueError的异常。skipkeys可以跳过那些非string对象当作key的处理.

import json

data= [ { 'a':'A', 'b':(2, 4), 'c':3.0, ('d',):'D tuple' } ]

try:
print json.dumps(data)
except (TypeError, ValueError) as err:
print 'ERROR:', err
print
print json.dumps(data, skipkeys=True)

输出:

ERROR: keys must be a string

[{"a": "A", "c": 3.0, "b": [2, 4]}]

让json支持自定义数据类型

以上例子都是基于python的built-in类型的,对于自定义类型的数据结构,json模块默认是没法处理的,会抛出异常:TypeError xx is not JSON serializable,此时你需要自定义一个转换函数:

import json  

class MyObj(object):
def __init__(self, s):
self.s = s
def __repr__(self):
return '<MyObj(%s)>' % self.s obj = .MyObj('helloworld') try:
print json.dumps(obj)
except TypeError, err:
print 'ERROR:', err #转换函数
def convert_to_builtin_type(obj):
print 'default(', repr(obj), ')'
# 把MyObj对象转换成dict类型的对象
d = { '__class__':obj.__class__.__name__,
'__module__':obj.__module__,
}
d.update(obj.__dict__)
return d print json.dumps(obj, default=convert_to_builtin_type)

输出:

ERROR: <MyObj(helloworld)> is not JSON serializable
default( <MyObj(helloworld)> )
{"s": "hellworld", "__module__": "MyObj", "__class__": "__main__"}
#注意:这里的class和module根据你代码的所在文件位置不同而不同

相反,如果要把json decode 成python对象,同样也需要自定转换函数,传递给json.loads方法的object_hook参数:

#jsontest.py

import json

class MyObj(object):

    def __init__(self,s):
self.s = s def __repr__(self): return "<MyObj(%s)>" % self.s def dict_to_object(d):
if '__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
module = __import__(module_name) print "MODULE:",module class_ = getattr(module,class_name) print "CLASS",class_ args = dict((key.encode('ascii'),value) for key,value in d.items()) print 'INSTANCE ARGS:',args inst = class_(**args)
else:
inst = d
return inst encoded_object = '[{"s":"helloworld","__module__":"jsontest","__class__":"MyObj"}]' myobj_instance = json.loads(encoded_object,object_hook=dict_to_object)
print myobj_instance

输出:

MODULE: <module 'jsontest' from 'E:\Users\liuzhijun\workspace\python\jsontest.py'>
CLASS <class 'jsontest.MyObj'>
INSTANCE ARGS: {'s': u'helloworld'}
[<MyObj(helloworld)>]
MODULE: <module 'jsontest' from 'E:\Users\liuzhijun\workspace\python\jsontest.py'>
CLASS <class 'jsontest.MyObj'>
INSTANCE ARGS: {'s': u'helloworld'}
[<MyObj(helloworld)>]

使用Encoder与Decoder类实现json编码的转换

JSONEncoder有一个迭代接口iterencode(data),返回一系列编码的数据,他的好处是可以方便的把逐个数据写到文件或网络流中,而不需要一次性就把数据读入内存.

import json

encoder = json.JSONEncoder()
data = [ { 'a':'A', 'b':(2, 4), 'c':3.0 } ] for part in encoder.iterencode(data):
print 'PART:', part

输出:

PART: [
PART: {
PART: "a"
PART: :
PART: "A"
PART: ,
PART: "c"
PART: :
PART: 3.0
PART: ,
PART: "b"
PART: :
PART: [2
PART: , 4
PART: ]
PART: }
PART: ]

encode方法等价于''.join(encoder.iterencode(),而且预先会做些错误检查(比如非字符串作为dict的key),对于自定义的对象,我们只需从些JSONEncoder的default()方法,其实现方式与上面提及的函数convet_to_builtin_type()是类似的。

import json
import json_myobj class MyObj(object): def __init__(self,s):
self.s = s def __repr__(self):
return "<MyObj(%s)>" % self.s class MyEncoder(json.JSONEncoder): def default(self, obj):
print 'default(', repr(obj), ')'
# Convert objects to a dictionary of their representation
d = { '__class__':obj.__class__.__name__,
'__module__':obj.__module__,
}
d.update(obj.__dict__)
return d obj = json_myobj.MyObj('helloworld')
print obj
print MyEncoder().encode(obj)

输出:

<MyObj(internal data)>
default( <MyObj(internal data)> )
{"s": "helloworld", "__module__": "Myobj", "__class__": "MyObj"}

从json对Python对象的转换:

class MyDecoder(json.JSONDecoder):

    def __init__(self):
json.JSONDecoder.__init__(self, object_hook=self.dict_to_object) def dict_to_object(self, d):
if '__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
module = __import__(module_name)
print 'MODULE:', module
class_ = getattr(module, class_name)
print 'CLASS:', class_
args = dict( (key.encode('ascii'), value) for key, value in d.items())
print 'INSTANCE ARGS:', args
inst = class_(**args)
else:
inst = d
return inst encoded_object = '[{"s": "helloworld", "__module__": "jsontest", "__class__": "MyObj"}]' myobj_instance = MyDecoder().decode(encoded_object)
print myobj_instance

输出:

MODULE: <module 'jsontest' from 'E:\Users\liuzhijun\workspace\python\jsontest.py'>
CLASS: <class 'jsontest.MyObj'>
INSTANCE ARGS: {'s': u'helloworld'}
[<MyObj(helloworld)>]

json格式字符串写入到文件流中

上面的例子都是在内存中操作的,如果对于大数据,把他编码到一个类文件(file-like)中更合适,load()dump()方法就可以实现这样的功能。

import json
import tempfile data = [ { 'a':'A', 'b':(2, 4), 'c':3.0 } ] f = tempfile.NamedTemporaryFile(mode='w+')
json.dump(data, f)
f.flush() print open(f.name, 'r').read()

输出:

[{"a": "A", "c": 3.0, "b": [2, 4]}]

类似的:

import json
import tempfile f = tempfile.NamedTemporaryFile(mode='w+')
f.write('[{"a": "A", "c": 3.0, "b": [2, 4]}]')
f.flush()
f.seek(0) print json.load(f)

输出:

[{u'a': u'A', u'c': 3.0, u'b': [2, 4]}]

参考:
http://docs.python.org/2/library/json.html
http://www.cnblogs.com/coser/archive/2011/12/14/2287739.html
http://pymotw.com/2/json/

Python处理JSON(转)的更多相关文章

  1. Json概述以及python对json的相关操作

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器解析和生成.它基于JavaScript Programming Langu ...

  2. 使用Python解析JSON数据的基本方法

    这篇文章主要介绍了使用Python解析JSON数据的基本方法,是Python入门学习中的基础知识,需要的朋友可以参考下:     ----------------------------------- ...

  3. python 序列化 json pickle

    python的pickle模块实现了基本的数据序列和反序列化.通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储:通过pickle模块的反序列化操作,我们能够从文件 ...

  4. Python处理json格式的数据文件(一些坑、一些疑惑)

    这里主要说最近遇到的一个问题,不过目前只是换了一种思路先解决了,脑子里仍然有疑惑,只能怪自己太菜. 最近要把以前爬的数据用一下了,先简单的过滤一下,以前用scrapy存数据的时候为了省事也为了用一下它 ...

  5. Python处理JSON

    从开源中国的博客搬来,合并博客 一.JSON是什么? JSON是一种轻量级的数据交换格式 二.Python处理JSON的思维 其实很容易理解,无非是将数据编成JSON格式数据和吧JSON格式的数据解析 ...

  6. Python处理JSON数据

    python解析json时为了方便,我们首先安装json模块,这里选择demjson,官方网址是:http://deron.meranda.us/python/demjson/ 访问之后点击页面的的D ...

  7. Json概述以及python对json的相关操作(转)

    什么是json: JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器解析和生成.它基于JavaScript Programm ...

  8. python 格式化 json输出

    利用python格式化json 字符串输出. $ echo '{"json":"obj"}' | python -m json.tool 利用python -m ...

  9. python解析json

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 引用 import json 编码:把一个Python对象编码转换成Json字符串 json.dumps ...

  10. python 解析json loads dumps

    认识 引用模块 重要函数 案例 排序 缩进参数 压缩 参考 认识 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于JavaScript(Standa ...

随机推荐

  1. java中初始化对象变量的方法

    1.在类定义对象的地方初始化 2.在类构造器中初始化 3.在正要使用这些对象之前,惰性初始化,或者叫惰性载入 4.使用实例初始化    在方法里使用初始化

  2. python测试开发django-9.使用navicat连接mysql

    前言 navicat 是一个连接数据库的可视化工具,可以连接mysql和oracle做一些简单增删改查,对于初学者来说非常方便的 navicat安装 navicat版本比较多,分享一个我经常用的版本 ...

  3. 玩转rocketMQ

    下载地址https://github.com/alibaba/RocketMQ 安装环境需要jdk,maven,git http://maven.apache.org/download.html

  4. SQL_求集合中每天最大时间记录的总和

    --问题求 集合中每天最大时间的总和 表中的数据 列: 用户 分数 时间 A 2 2014-01-01 01:00:00 A 2 2014-01-01 02:00:00 A 2 2014-01-01 ...

  5. 日期时间篇asctime ctime gettimeofday gmtime localtime mktime settimeofday time

    asctime(将时间和日期以字符串格式表示) 相关函数 time,ctime,gmtime,localtime 表头文件 #include<time.h> 定义函数 char * asc ...

  6. Matlab注释多行和取消多行注释的快捷键

    matlab里注释符号是%,只是单行注释,可是没有多行注释符号,就像C/C++/Java中都有多行注释符号/*  */. 如果利用单行注释的方式手工注释一段程序会很麻烦,matlab软件自带快捷键支持 ...

  7. freetds简介、安装、配置及使用介绍

    什么是FreeTDS 简单的说FreeTDS是一个程序库,可以实现在Linux系统下访问微软的SQL数据库! FreeTDS 是一个开源(如果你喜欢可以称为自由)的程序库,是TDS(表列数据流 )协议 ...

  8. 第十二章 ThreadPoolExecutor使用 + 工作机理 + 生命周期

    1.最基础的线程池ThreadPoolExecutor 使用方式: /** * ThreadPoolExecutor测试类 * 注意: * 1.ThreadPoolExecutor是一个线程池 * 2 ...

  9. go语言基础之复合类型

    1.分类 类型 名称 长度 默认值 说明 pointer 指针 nil array 数组 0 slice 切片 nil 引⽤类型 map 字典 nil 引⽤类型 struct 结构体 2.指针 指针是 ...

  10. C语言存储类型

    看c专家编程,有说存储类型一直不太清楚.看到一篇文章讲解c的存储类型,讲解了c语言中的各种变量的存储类型,而且是从进程.内存的角度讲解的,以前从没有这样理解过,觉得挺有用的,在这里转载过来. 首先要来 ...