一香浩、定義
JSON(JavaScript Object Notation楷扬,JavaScript對(duì)象表示法,讀作“Jason”)是一種由道格拉斯·克羅克福特構(gòu)想和設(shè)計(jì)浑娜、輕量級(jí)的數(shù)據(jù)交換語言享扔,該語言以易于讓人閱讀的文字為基礎(chǔ)底桂,用來傳輸由屬性值或者序列性的值組成的數(shù)據(jù)對(duì)象。盡管JSON是JavaScript的一個(gè)子集惧眠,但JSON是獨(dú)立于語言的文本格式籽懦,并且采用了類似于C語言家族的一些習(xí)慣。
JSON 數(shù)據(jù)格式與語言無關(guān)氛魁,脫胎自JavaScript暮顺,但當(dāng)前很多編程語言都支持 JSON 格式數(shù)據(jù)的生成和解析。JSON 的官方 MIME 類型是 application/json秀存,文件擴(kuò)展名是 .json捶码。詳見:https://baike.baidu.com/item/JSON/2462549?fr=aladdin
二、JSON的語法
在 JS 語言中或链,一切都是對(duì)象惫恼。因此,任何支持的類型都可以通過 JSON 來表示澳盐,例如字符串祈纯、數(shù)字、對(duì)象叼耙、數(shù)組等腕窥。
- 對(duì)象(字典)。使用花括號(hào)筛婉。
- 數(shù)組(列表)簇爆。使用方括號(hào)。
- 整形爽撒、浮點(diǎn)型冕碟、布爾類型還有null類型。
- 字符串類型(字符串必須要用雙引號(hào)匆浙,不能用單引號(hào))。
注意:json本質(zhì)上就是一個(gè)字符串厕妖。
三首尼、JSON與XML比較
JSON與XML最大的不同在于XML是一個(gè)完整的標(biāo)記語言,而JSON不是。這使得XML在程序判讀上需要比較多的功夫软能。主要的原因在于XML的設(shè)計(jì)理念與JSON不同迎捺。XML利用標(biāo)記語言的特性提供了絕佳的延展性(如XPath),在數(shù)據(jù)存儲(chǔ)查排,擴(kuò)展及高級(jí)檢索方面具備對(duì)JSON的優(yōu)勢(shì)凳枝,而JSON則由于比XML更加小巧,以及瀏覽器的內(nèi)建快速解析支持跋核,使得其更適用于網(wǎng)絡(luò)數(shù)據(jù)傳輸領(lǐng)域岖瑰。
實(shí)例比較:用XML表示中國(guó)部分省市數(shù)據(jù)如下:
<?xml version="1.0" encoding="utf-8"?>
<country>
<name>中國(guó)</name>
<province>
<name>黑龍江</name>
<cities>
<city>哈爾濱</city>
<city>大慶</city>
</cities>
</province>
<province>
<name>廣東</name>
<cities>
<city>廣州</city>
<city>深圳</city>
<city>珠海</city>
</cities>
</province>
<province>
<name>臺(tái)灣</name>
<cities>
<city>臺(tái)北</city>
<city>高雄</city>
</cities>
</province>
<province>
<name>新疆</name>
<cities>
<city>烏魯木齊</city>
</cities>
</province>
</country>
用JSON表示如下:
{
"name": "中國(guó)",
"province": [{
"name": "黑龍江",
"cities": {
"city": ["哈爾濱", "大慶"]
}
}, {
"name": "廣東",
"cities": {
"city": ["廣州", "深圳", "珠海"]
}
}, {
"name": "臺(tái)灣",
"cities": {
"city": ["臺(tái)北", "高雄"]
}
}, {
"name": "新疆",
"cities": {
"city": ["烏魯木齊"]
}
}]
}
可以看到,JSON 簡(jiǎn)單的語法格式和清晰的層次結(jié)構(gòu)明顯要比 XML 容易閱讀砂代,并且在數(shù)據(jù)交換方面蹋订,由于 JSON 所使用的字符要比 XML 少得多,可以大大得節(jié)約傳輸數(shù)據(jù)所占用的帶寬刻伊。
四露戒、JSON序列化為字符串
json.dumps()這個(gè)函數(shù),接受python的基本數(shù)據(jù)類型捶箱,然后將其序列化為string智什,注意這里的基本數(shù)據(jù)類型指的是int
、float
丁屎、str
荠锭、list
、dict
悦屏、tuple
节沦。
實(shí)例:
import json
data_json = {
"name": "中國(guó)",
"province": [{
"name": "黑龍江",
"cities": {
"city": ["哈爾濱", "大慶"]
}
}, {
"name": "廣東",
"cities": {
"city": ["廣州", "深圳", "珠海"]
}
}, {
"name": "臺(tái)灣",
"cities": {
"city": ["臺(tái)北", "高雄"]
}
}, {
"name": "新疆",
"cities": {
"city": ["烏魯木齊"]
}
}]
}
data_string_ascii = json.dumps(data_json)
data_string = json.dumps(data_json,ensure_ascii=False)
print(data_string_ascii)
print('數(shù)據(jù)類型為:{}'.format(type(data_string_ascii)))
print(data_string)
print('數(shù)據(jù)類型為:{}'.format(type(data_string)))
結(jié)果:
{"name": "\u4e2d\u56fd", "province": [{"name": "\u9ed1\u9f99\u6c5f", "cities": {"city": ["\u54c8\u5c14\u6ee8", "\u5927\u5e86"]}}, {"name": "\u5e7f\u4e1c", "cities": {"city": ["\u5e7f\u5dde", "\u6df1\u5733", "\u73e0\u6d77"]}}, {"name": "\u53f0\u6e7e", "cities": {"city": ["\u53f0\u5317", "\u9ad8\u96c4"]}}, {"name": "\u65b0\u7586", "cities": {"city": ["\u4e4c\u9c81\u6728\u9f50"]}}]}
數(shù)據(jù)類型為:<class 'str'>
{"name": "中國(guó)", "province": [{"name": "黑龍江", "cities": {"city": ["哈爾濱", "大慶"]}}, {"name": "廣東", "cities": {"city": ["廣州", "深圳", "珠海"]}}, {"name": "臺(tái)灣", "cities": {"city": ["臺(tái)北", "高雄"]}}, {"name": "新疆", "cities": {"city": ["烏魯木齊"]}}]}
數(shù)據(jù)類型為:<class 'str'>
注意:json
在dump
的時(shí)候,只能存放ascii
的字符础爬,因此會(huì)將中文進(jìn)行轉(zhuǎn)義甫贯。若要顯示中文,這時(shí)候我們可以使用ensure_ascii=False
關(guān)閉這個(gè)特性看蚜。
五叫搁、字符串反序列化為python基本數(shù)據(jù)類型
json.loads()函數(shù),接受一個(gè)合法字符串供炎,然后發(fā)序列為python的基本數(shù)據(jù)類型渴逻。
import json
data_string = '{"name": "中國(guó)", "province": [{"name": "黑龍江", "cities": {"city": ["哈爾濱", "大慶"]}}, {"name": "廣東", "cities": {"city": ["廣州", "深圳", "珠海"]}}, {"name": "臺(tái)灣", "cities": {"city": ["臺(tái)北", "高雄"]}}, {"name": "新疆", "cities": {"city": ["烏魯木齊"]}}]}'
data_json = json.loads(data_string,encoding='utf-8')
print('原數(shù)據(jù)類型為:{}'.format(type(data_string)))
print('反序列過后數(shù)據(jù)類型為:{}'.format(type(data_json)))
print(data_json)
結(jié)果:
原數(shù)據(jù)類型為:<class 'str'>
反序列過后數(shù)據(jù)類型為:<class 'dict'>
{'name': '中國(guó)', 'province': [{'name': '黑龍江', 'cities': {'city': ['哈爾濱', '大慶']}}, {'name': '廣東', 'cities': {'city': ['廣州', '深圳', '珠海']}}, {'name': '臺(tái)灣', 'cities': {'city': ['臺(tái)北', '高雄']}}, {'name': '新疆', 'cities': {'city': ['烏魯木齊']}}]}
注意:在json.loads()前加上錯(cuò)誤處理,否則字符串中有非法字符音诫。而沒有捕捉到惨奕,那么程序就會(huì)崩潰。
六竭钝、文件的讀寫操作
1梨撞、將json數(shù)據(jù)直接dump到文件中:
json
模塊中除了dumps
函數(shù)雹洗,還有一個(gè)dump
函數(shù),這個(gè)函數(shù)可以傳入一個(gè)文件指針卧波,直接將字符串dump
到文件中时肿。示例代碼如下:
import json
data_json = {
"name": "中國(guó)",
"province": [{
"name": "黑龍江",
"cities": {
"city": ["哈爾濱", "大慶"]
}
}, {
"name": "廣東",
"cities": {
"city": ["廣州", "深圳", "珠海"]
}
}, {
"name": "臺(tái)灣",
"cities": {
"city": ["臺(tái)北", "高雄"]
}
}, {
"name": "新疆",
"cities": {
"city": ["烏魯木齊"]
}
}]
}
with open('city.json','w',encoding='utf-8') as fp:
json.dump(data_json,fp,ensure_ascii=False)
city.json文件顯示結(jié)果:
{"name": "中國(guó)", "province": [{"name": "黑龍江", "cities": {"city": ["哈爾濱", "大慶"]}}, {"name": "廣東", "cities": {"city": ["廣州", "深圳", "珠海"]}}, {"name": "臺(tái)灣", "cities": {"city": ["臺(tái)北", "高雄"]}}, {"name": "新疆", "cities": {"city": ["烏魯木齊"]}}]}
注意:json
在dump
的時(shí)候,只能存放ascii
的字符港粱,因此會(huì)將中文進(jìn)行轉(zhuǎn)義螃成。若要顯示中文,這時(shí)候我們可以使用ensure_ascii=False
關(guān)閉這個(gè)特性查坪。另外寸宏,文件編碼格式需要指定為uft-8,否則打開的為非中文咪惠。
2击吱、直接從文件中讀取json:
import json
with open('city.json','r',encoding='utf8') as fp:
data_string = json.load(fp)
print(data_string)
print(type(data_string))
結(jié)果:
{'name': '中國(guó)', 'province': [{'name': '黑龍江', 'cities': {'city': ['哈爾濱', '大慶']}}, {'name': '廣東', 'cities': {'city': ['廣州', '深圳', '珠海']}}, {'name': '臺(tái)灣', 'cities': {'city': ['臺(tái)北', '高雄']}}, {'name': '新疆', 'cities': {'city': ['烏魯木齊']}}]}
<class 'dict'>