Python处理JSON

概念

序列化(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. hdu 5471(状压DP or 容斥)

    想了最复杂的思路,用了最纠结的方法,花了最长的时间,蒙了一种规律然后莫名其妙的过了. MD 我也太淼了. 后面想了下用状压好像还是挺好写的,而且复杂度也不高.推出的这个容斥的规律也没完全想透我就CAO ...

  2. 用SQL语句生成唯一标识

    以前都是在代码中生成GUID值,然后保存到数据库中去,今天发现用sql也能生成GUID值,觉得很新奇,所以记下来. sellect newid();  //得到的即为GUID值 此sql内置函数返回的 ...

  3. JavaWeb 之邮件发送

    1. 邮件协议概述 SMTP(Simple Mail Transfer Protocol, 简单邮件传输协议) 发邮件协议; POP3(Post Office Protocol Version 3, ...

  4. (2)linux未使用eth0,未使用IPV4导致无法连接

    首先ifconfig查看网络IP 看,我这里默认启用了2个网卡,一个是eth0,另一个是lo(基于loopback方式) 1.如果有eth0则做:界面修改 (1)输入命令setup,选择network ...

  5. 使用Kotlin开发Android应用 - 环境搭建 (1)

    一. 在Android Studio上安装Kotlin插件 按快捷键Command+, -> 在Preferences界面找到Plugins -> 点击Browse repositorie ...

  6. python中json.dumps使用的坑以及字符编码

    我们知道,python中的字符串分普通字符串和unicode字符串,一般从数据库中读取的字符串会自动被转换为unicode字符串 下面回到重点,使用json.dumps时,一般的用法为: >&g ...

  7. javascript高级语法二

    一.BOM对象 1.什么是BOM对象? BOM是浏览器对象模型,核心对象就是window,所有浏览器都支持 window 对象.一个html文档对应一个window对象,主要功能是控制浏览器窗口的, ...

  8. golang模板语法简明教程(后面有福利哦)

    template是go 语言web开发中必不可少的,特此记录下来: [模板标签] 模板标签用"{{"和"}}"括起来   [注释] {{/* a comment ...

  9. python之路(sed,函数,三元运算)

    python之路(sed,函数,三元运算) 一.sed集合 1.set无序,不重复序列 2.创建 se = {11,22,33,33,44} list() #只要是一个类加上()自动执行 list _ ...

  10. webpack基础配置

    webpack运行规则: Webpack 会给每个模块分配一个唯一的id并通过这个id索引和访问模块.在页面启动时,会先执行入口文件中的代码,其它模块会在运行 require 的时候再执行. 运行时主 ...