目录
1.JSON 是什么?
JSON 的全称是 JavaScript Object Notation,是⼀种轻量级的数据交换格式。最初,JSON 只是JavaScript 的⼦集,但由于其简单易⽤⽽迅速⾛红。
现今⼤部分编程语⾔都⽀持对 JSON 的解析与⽣成,⽽近些年异军突起的 NoSQL 数据库也多参照 JSON 来设计数据存储格式,例如 Mongodb 的BSON(Binary JSON)。
JSON 有以下六种数据类型:number、boolean、string、null、array、object。前三种很好理解,第四个 null 对应 Python 的 None,最后两种,对应 Python 的列表和字典。
{
"name": "⼩明",
"age": 14,
"gender": true,
"grade": null,
"skills": [
"JavaScript",
"Java",
"Python"
]
}
2.JSON 与XML 的优劣差异?
在 JSON 出现之前,⼈们⽤ XML 在⽹络上交换数据,在 JSON 出现后,它基本上就取代了 XML 的位置。两者的共同之处显⽽易⻅,它们都是结构化的语⾔,都可以⽤于⽹络数据的交换。
两者最⼤的差异在于它们的“出身”不同,也就是它们被创造的⽬的不同。
XML 是 W3C(万维⽹联盟)发布的可扩展标记语⾔(Extensible Markup Language),最初设计来弥补 HTML 的 不 ⾜ , 以 强 ⼤ 的 扩 展 性 满 ⾜ ⽹ 络 信 息 发 布 的 需 要 , 与 它 “ 同 级 ” 的 有 : XHTML\CSS\ECMAScript等。
它包含 DTD、XSD、XPath、XSL 等⼀⼤堆复杂的规范,在数据存储、扩展及⾼级检索等⽅⾯都有作⽤。后来被⽤于⽹络数据交换,颇有点⼤材⼩⽤的意思,虽然可胜任,却也有点复杂和冗余。
⽽ JSON 是 ECMAScript 标准的⼦集,设计之初就是为了克服 XML 在数据交换上的劣势,所以⼀⽅
⾯,它像 XML ⼀样具有简洁⽽清晰的层次结构,另⼀⽅⾯,它⽐ XML ⼩巧精致,更加适⽤于⽹络数据的传输。
JSON 也不是没有缺点,当结构层级很多的时候,它会让⼈陷⼊繁琐复杂的数据节点查找中,在可读性上要⽐ XML 差。
3.将 Python 对象编码成 JSON 字符串
将 Python 的对象转化为字符串,这个过程也称为序列化,与之相对,将 JSON 字符串转化为 Python 对象,这个过程被称为反序列化。
序列化格式如下,json.dumps() 把 Python 对象序列化,json.dump() 先序列化,然后将内容存⼊⽂件:
json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw) json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False,
**kw)
In [1]:import json
In [2]:d = dict(name='Tom', age='8', score=88)
In [3]:json.dumps(d)
Out[3]:'{"name": "Tom", "age": "8", "score": 88}'
In [4]:with open('test.json', 'w') as f:
...:json.dump(d, f)
⽤的⽐较多的参数有:
- ensure_ascii=True 设置是否编码为ASCII,默认是,若False,则使⽤原编码格式
- indent=None 设置打印时缩进,默认不缩进
- separators=None 设置分隔符,取值是(item_separator, dict_separator)元组,默认为(‘,’,’:’),这表示keys之间⽤“,”隔开,⽽key和value之间⽤“:”隔开
- sort_keys=False 设置按key值排序,默认不排序
In[15]:d = dict(name='Python猫',age='8',score=88)
In[16]:json.dumps(d)
Out[16]:'{"name":"Python\\u732b","age":"8","score":88}'
In[17]:json.dumps(d,ensure_ascii=False,indent=4,sort_keys=True)
Out[17]:'{\n"age":"8",\n"name":"Python猫",\n"score":88\n}'
In[18]:print(json.dumps(d,ensure_ascii=False,indent=4,sort_keys=True))
{
"age": "8",
"name": "Python猫",
"score": 88
}
4.将已编码的 JSON 字符串解码为 Python 对象
反序列化格式如下,json.loads() 从内存中读取内容解析,json.load() 从⽂件中读取内容解析:
- json.loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
- json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
In[1]:import json
In[2]:d = dict(name='Tom',age='8',score=88)
In[3]:tom_json = json.dumps(d)
In[4]:json.loads(tom_json)
Out[4]:{'age':'8','name':'Tom','score':88}
In [5]:with open('test.json','r') as f:
...:print(json.load(f))
{'name':'Tom','age':'8','score':88}
json.loads() ⽐ json.load() 多了⼀个 encoding 参数,可以将传⼊的字符串重新编码。
5.解决中⽂乱码问题
序列化的 ensure_ascii 参数与反序列化的 encoding 相对应,都是处理字符编码,⼀旦处理不好,就会导致中⽂乱码问题。
Python2 的字符编码乱七⼋糟,也⼴被⼈诟病,如果不幸遇到 Python2 项⽬,可参照如下例⼦解决。
字符串在 Python2 内部的表示是 unicode 编码。因此,在做编码转换时,需要以 unicode 作为中间编码,即先将其他编码的字符串解码(decode)成 unicode,再从 unicode 编码(encode)成另⼀种编码。
# -*- coding: utf-8 -*-
m = {'a':'你好'}
print m
=>{'a':'\xe4\xbd\xa0\xe5\xa5\xbd'}
print json.dumps(m)
=>{"a":"\u4f60\u597d"}
print json.dumps(m,ensure_ascii=False)
=>{"a":"浣犲ソ"}
print json.dumps(m,ensure_ascii=False).decode('utf8').encode('gb2312')
=>{"a":"你好"}
Python3 的默认编码格式是 utf-8,以上例⼦,只需要 ensure_ascii=False ,就能解决。