Json

来自linux中国网wiki
跳到导航 跳到搜索

基本知识

什么是json:

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。

JSON建构于两种结构:

“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。 这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。

json查看

jq . file.json

代码

对简单数据类型的encoding(编码) 和 decoding(解码)


使用dumps编码

使用简单的'''json.dumps''' 方法对简单数据类型进行编码,

例如:

In [1]: import json0

In [2]: obj = [[1,2,3],123,123.123,'abc',{'key1':(1,2,3),'key2':(4,5,6)}]

In [3]: encodedjson = json.dumps(obj)

In [4]: print repr(obj)
[[1, 2, 3], 123, 123.123, 'abc', {'key2': (4, 5, 6), 'key1': (1, 2, 3)}]

In [5]: print encodedjson
[[1, 2, 3], 123, 123.123, "abc", {"key2": [4, 5, 6], "key1": [1, 2, 3]}]

通过输出的结果可以看出,简单类型通过encode之后跟其原始的repr()输出结果非常相似,但是有些数据类型进行了改变,例如上例中的元组则转换为了列表。在json的编码过程中,会存在从python原始类型向json类型的转化过程,具体的转化对照如下:

Python                 JSON	

dict                  object	
list,tuple            array	
str,unicode           string	
int, long, float      number 
True                  true	
False                 false	
None                  null	

使用loads解码

json.dumps()方法返回了一个str对象encodedjson,我们接下来在对encodedjson进行decode(解码),得到原始数据,需要使用的json.loads()函数:

In [6]: decodejson = json.loads(encodedjson)
In [7]: print type(decodejson)
<type 'list'>
In [8]: print decodejson
[[1, 2, 3], 123, 123.123, u'abc', {u'key2': [4, 5, 6], u'key1': [1, 2, 3]}]

In [9]: print decodejson[4]['key1']
[1, 2, 3]

loads方法返回了原始的对象,但是仍然发生了一些数据类型的转化。比如,上例中‘abc’转化为了unicode类型。从json到python的类型转化对照如下:

JSON	Python

object	dict
array	list
string	unicode
number (int)	int, long
number (real)	float
true	True
false	False
null	None

json.dumps的常用参数

json.dumps方法提供了很多好用的参数可供选择,比较常用的有sort_keys(对dict对象进行排序,我们知道默认dict是无序存放的),separators,indent等参数。
排序功能使得存储的数据更加有利于观察,也使得对json输出的对象进行比较,例如:

In [10]: data1 = {'b':789,'c':456,'a':123}
In [11]: date2 ={'a':123, 'b':789,'c':456}
In [12]: d1 = json.dumps(data1,sort_keys=True)
In [14]: d2 = json.dumps(date2)

d3 = json.dumps(date2,sort_keys=True)

In [16]: print d1
{"a": 123, "b": 789, "c": 456}

In [19]: print d2
{"a": 123, "c": 456, "b": 789}

In [20]: print d3
{"a": 123, "b": 789, "c": 456}

In [21]: print d1==d2
False

In [22]: print d1==d3
True

上例中,本来data1和data2数据应该是一样的,但是由于dict存储的无序特性,造成两者无法比较。因此两者可以通过排序后的结果进行存储就避免了数据比较不一致的情况发生,但是排序后再进行存储,系统必定要多做一些事情,也一定会因此造成一定的性能消耗,所以适当排序是很重要的。


indent参数是缩进的意思,它可以使得数据存储的格式变得更加优雅。
In [23]: data1 = {'b':789,'c':456,'a':123}

In [24]: d1 = json.dumps(data1,sort_keys=True,indent=4)

In [25]: print d1
{
    "a": 123, 
    "b": 789, 
    "c": 456
}

In [26]: d1 = json.dumps(data1,sort_keys=True)

In [27]: print d1
{"a": 123, "b": 789, "c": 456}

输出的数据被格式化之后,变得可读性更强,但是却是通过增加一些冗余的空白格来进行填充的。json主要是作为一种数据通信的格式存在的,而网络通信是很在乎数据的大小的,无用的空格会占据很多通信带宽,所以适当时候也要对数据进行压缩。separator参数可以起到这样的作用,该参数传递是一个元组,包含分割对象的字符串。
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=4))
print 'dumps(data, separators):', len(json.dumps(data, separators=(',',':')))

输出:

DATA: {'a': 123, 'c': 456, 'b': 789} 
repr(data)             : 30 
dumps(data)            : 30 
dumps(data, indent=2)  : 46 
dumps(data, separators): 25

通过移除多余的空白符,达到了压缩数据的目的,而且效果还是比较明显的。

另一个比较有用的dumps参数是skipkeys,默认为False。 dumps方法存储dict对象时,key必须是str类型,如果出现了其他类型的话(1,2):123,那么会产生TypeError异常,如果开启该参数,设为True的话,则会比较优雅的过度。

In [30]: data = {'b':789,'c':456,(1,2):123}

In [31]: print json.dumps(data,skipkeys=True)
{"c": 456, "b": 789}

In [32]: print json.dumps(data)
TypeError 
TypeError: keys must be a string


常用命令

让python的json.dumps输出中文

 
python的json.dumps方法默认会输出成这种格式"\u535a\u5ba2\u56ed",。

要输出中文需要指定ensure_ascii参数为False,如下代码片段:0

json.dumps({'text':"中文"},ensure_ascii=False,indent=2)


{ "smg": "域名linuxsa.org添加成功!", "emg": "获取信息失败!" }0

<pre> 
首先说明基本功能:

dumps是将dict转化成str格式,loads是将str转化成dict格式。

dump和load也是类似的功能,只是与文件操作结合起来了。


json.dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding="utf-8", default=None, sort_keys=False, **kw)¶
将obj序列化为 JSON 格式流到fp ( .write()-支持类文件对象)

注:实际中dump用的较少。 

压缩编码:

>>>
>>> import json
>>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'))
'[1,2,3,{"4":5,"6":7}]

解码 JSON:

>>>
>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
[u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
u'"foo\x08ar'
>>> from StringIO import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
[u'streaming API']

处理自己的数据类型

json模块不仅可以处理普通的python内置类型,也可以处理我们自定义的数据类型,而往往处理自定义的对象是很常用的。

暂时省略请见 Json概述以及python对json的相关操作

python操作json

09 获取json中key为name的所有值



输入:

[
   {
      "id":1,
      "name":"name1",
      "color":[
         "red",
         "green"
      ]
   },
   {
      "id":2,
      "name":"name2",
      "color":[
         "pink",
         "yellow"
      ]
   }
]

输出:

["name1", "name2"]



示例代码:

import json

sampleJson = """[
   {
      "id":1,
      "name":"name1",
      "color":[
         "red",
         "green"
      ]
   },
   {
      "id":2,
      "name":"name2",
      "color":[
         "pink",
         "yellow"
      ]
   }
]"""

data = []
try:
    data = json.loads(sampleJson)
except Exception as e:
    print(e)

dataList = [item.get('name') for item in data]
print(dataList)

Python 操作 JSON 的 9 个示例

ruby操作json

Learn_ruby#ruby操作json

参考

json 格式转换

http://usyiyi.cn/translate/python_278/library/json.html

Python操作json的标准api库参考

jso官方说明参见:http://json.org/ http://json.org/json-zh.html

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