JSON序列與反序列

一香浩、定義

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ù)類型指的是intfloat丁屎、str荠锭、listdict悦屏、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'>

注意:jsondump的時(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": ["烏魯木齊"]}}]}

注意:jsondump的時(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'>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市遥昧,隨后出現(xiàn)的幾起案子覆醇,更是在濱河造成了極大的恐慌,老刑警劉巖炭臭,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件永脓,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鞋仍,警方通過查閱死者的電腦和手機(jī)常摧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來威创,“玉大人落午,你說我怎么就攤上這事《遣颍” “怎么了溃斋?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)吸申。 經(jīng)常有香客問我梗劫,道長(zhǎng),這世上最難降的妖魔是什么截碴? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任梳侨,我火速辦了婚禮,結(jié)果婚禮上日丹,老公的妹妹穿的比我還像新娘走哺。我一直安慰自己,他們只是感情好哲虾,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布丙躏。 她就那樣靜靜地躺著齐帚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪彼哼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天湘今,我揣著相機(jī)與錄音敢朱,去河邊找鬼。 笑死摩瞎,一個(gè)胖子當(dāng)著我的面吹牛拴签,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播旗们,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼蚓哩,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了上渴?” 一聲冷哼從身側(cè)響起岸梨,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稠氮,沒想到半個(gè)月后曹阔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡隔披,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年赃份,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奢米。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抓韩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鬓长,到底是詐尸還是另有隱情谒拴,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布痢士,位于F島的核電站彪薛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏怠蹂。R本人自食惡果不足惜善延,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望城侧。 院中可真熱鬧易遣,春花似錦、人聲如沸嫌佑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至揩魂,卻和暖如春幽邓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背火脉。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工牵舵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人倦挂。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓畸颅,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親方援。 傳聞我的和親對(duì)象是個(gè)殘疾皇子没炒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容