Python模块学习之json
最近接触到一些JSON的知识,顺便学习一下Python对Json的操作。
一、JSON简介:
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript(StandardECMA-262 3rd Edition - December 1999)的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript,Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。
JSON 语法规则(重要性就不说了)
- 数据在名称/值对中
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
JSON和Python中的字典非常像。记得从某个地方看到过:JSON就是Python字典的字符串表示,但是字典作为一个复杂对象是无法直接转换成定义它的代码的字符串,因为JSON是纯文本。
二、Python的JSON模块
python自带JSON处理模块(2.6版本之后),模块名就叫做Python。直接在Python Shell中输入help(json)就可以查看许多相关的信息。其实无外乎是python类型的数据和JSON格式数据之间的相互转换。从Python生成JSON对应模块中的dump和dumps方法,解析JSON成Python的数据类型对应模块中的loads和load方法。
1.Python生成JSON对应模块中的dump和dumps方法:
两个方法的区别在于dumps方法处理的是字符串,dump处理的是文件对象,比如StringIO转化过后的字符串。
import json from StringIO import StringIO a = ['foo', {'bar': ('baz', None, 1.0, 2)}] print("a 的类型是 %s" % type(a)) b = json.dumps(a) print("转换成JSON格式:%s, 类型是 %s" % (b, type(b))) #["foo", {"bar": ["baz", null, 1.0, 2]}],类型是str io = StringIO() json.dump(a, io) print("把原类型编码到文件对象:%s, 类型是 %s" % (io.getvalue(), type(io))) #把json编码数据导向到文件对象
JSON编码过程中会对原数据进行一些变换,具体转换如下表:
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str, unicode | string |
int, long, float | number |
True | true |
False | false |
None | null |
dumps方法有几个比较有用的参数:sort_keys控制是否排序(True or False),indent定义缩进大小(int类型),separators是一个元组,定义分隔符的类型。具体示例如下:
#pretty print s = json.dumps(a, sort_keys=True, indent=4, separators=('!', '?')) #分隔符这里只是测试,一般保持默认逗号和分号即可 print s #输出结果为 [ "foo"! { "bar"?[ "baz"! null! 1.0! 2 ] } ]
另一个比较有用的dumps参数是skipkeys,默认为False。 dumps方法编码dict对象时,key必须是str类型(数字也可以,但是元组不可以),如果出现了其他类型的话,那么会产生TypeError异常(需要注意),如果该参数设为True的话,则会跳过异常的key。示例如下:
try: data = {'a':1, 'b':2, (1,):3} json.dumps(data) except TypeError,e: print e #keys must be a string print json.dumps(data,skipkeys=True) #{"a": 1, "b": 2} data = {'a':1, 'b':2, 1:3} print json.dumps(data) #注意,此处不报错而是转成了字符串类型:{"a": 1, "1": 3, "b": 2}
2、解析JSON成Python的数据类型对应模块中的loads和load方法
两个方法的区别同dump和dumps。具体示例如下:
c = json.loads(b) print("从JSON格式转成python类型:%s, 类型是 %s" % (c, type(c))) #[u'foo', {u'bar': [u'baz', None, 1.0, 2]}],类型是list io = StringIO('["streaming API"]') d = json.load(io) print("从JSON格式解码到流文件中:%s, 类型是 %s" % (d, type(d))) #[u'streaming API'], 类型是 <type 'list'>
可以看出来loads方法返回了原始的对象,但是做了数据类型的转化,字符串转换成unicode类型,原来的tuple也没有转换过来,只转成了list类型。对应的默认转换如下:
JSON | Python |
---|---|
object | dict |
array | list |
string | unicode |
number (int) | int, long |
number (real) | float |
true | True |
false | False |
null | None |
此外官方文档中还有两个方法,暂时还没有研究过,待补充:
JSONDecoder([encoding[,object_hook[, parse_float[,parse_int[, parse_constant[,strict[, object_pairs_hook]]]]]]])
JSONEncoder([skipkeys[,ensure_ascii[, check_circular[,allow_nan[, sort_keys[,indent[, separators[,encoding[, default]]]]]]]]])