一、背景知識(shí)
引用百科描述如下,具體請自行搜索相關(guān)介紹:
JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式。它基于 JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一個(gè)子集。 JSON 采用完全獨(dú)立于語言的文本格式,但是也使用了類似于C語言家族的習(xí)慣(包括 C, C++, C#, Java, JavaScript, Perl, Python 等)。這些特性使 JSON 成為理想的數(shù)據(jù)交換語言。易于人閱讀和編寫,同時(shí)也易于機(jī)器解析和生成(網(wǎng)絡(luò)傳輸速度快)。
表示方法:
示例:
{"programmers":[
{"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"},
{"firstName":"Jason","lastName":"Hunter","email":"bbbb"},
{"firstName":"Elliotte","lastName":"Harold","email":"cccc"}
],
"authors":[
{"firstName":"Isaac","lastName":"Asimov","genre":"sciencefiction"},
{"firstName":"Tad","lastName":"Williams","genre":"fantasy"},
{"firstName":"Frank","lastName":"Peretti","genre":"christianfiction"}
]}
unicode 標(biāo)準(zhǔn)描述了字符如何對應(yīng)編碼點(diǎn)(code point),使用 16 進(jìn)制表示 00 00.
PYTHON 中,basestring 派生了 unicode 類型和 str 類型
unicode 字符串是一個(gè)編碼點(diǎn)序列,該序列在內(nèi)存中會(huì)被表示成一組字節(jié)(0-255),str 是指 8 字節(jié)流。
unicode 字符串可以通過 encode 函數(shù)轉(zhuǎn)換為 str;str 可以通過 decode 轉(zhuǎn)換為 unicode。編解碼類型一般是 utf-8
示例:
>>> u"中國".encode('utf-8')
'\xe4\xb8\xad\xe5\x9b\xbd' #將 unicode 字符串編碼為 str
>>> '\xe4\xb8\xad\xe5\x9b\xbd'.decode('utf-8')
u'\u4e2d\u56fd' #將 str 解碼為 unicode 字符串
從文件中讀和寫入文件的操作都應(yīng)該是操作的 8 位字節(jié)流,如果將 unicode 字符串寫入文件,需要進(jìn)行編碼操作;如果從文件中讀 unicode 字符串,首先讀取出來的是 8 位字節(jié)流需要進(jìn)行解碼操作。
一般功能代碼中都直接操作 unicode 字符串,而只在寫數(shù)據(jù)或讀數(shù)據(jù)時(shí)添加對應(yīng)的編解碼操作。
當(dāng)兩個(gè)進(jìn)程在進(jìn)行遠(yuǎn)程通信時(shí),彼此可以發(fā)送各種類型的數(shù)據(jù)。無論是何種類型的數(shù)據(jù),都會(huì)以二進(jìn)制序列的形式在網(wǎng)絡(luò)上傳送。發(fā)送方需要把這個(gè)對象轉(zhuǎn)換為字節(jié)序列,才能在網(wǎng)絡(luò)上傳送;接收方則需要把字節(jié)序列再恢復(fù)為對象。
把對象轉(zhuǎn)換為字節(jié)序列的過程稱為對象的序列化,比如把一個(gè)字典對象以某種格式(JSON)寫到文件中;把字節(jié)序列恢復(fù)為對象的過程稱為對象的反序列化,比如讀取某種格式化(JSON)的文件,構(gòu)造一個(gè)字典對象。
根據(jù) HOWTO-UNICODE 的知識(shí),把網(wǎng)絡(luò)可以看做是一個(gè)文件,發(fā)送方寫數(shù)據(jù)到網(wǎng)絡(luò)時(shí)需要進(jìn)行編碼,接收方讀取數(shù)據(jù)時(shí)需要進(jìn)行解碼。也就是說序列化的同時(shí)會(huì)進(jìn)行編碼,反序列化的同時(shí)會(huì)進(jìn)行解碼。
二、simplejson
simplejson 是 json 標(biāo)準(zhǔn)模塊的擴(kuò)展(基礎(chǔ)功能相同),是 pypi 提供的拓展模塊,需要另行安裝。不過可以使用 python 自帶的 json 庫,基本是相同的使用方法(提供的接口功能基本一致)。在 python 的 library 文檔中將 JSON 歸為網(wǎng)絡(luò)數(shù)據(jù)控制類,很好的說明了他們的用途,主要用于網(wǎng)絡(luò)數(shù)據(jù)控制,編解碼等。但是也具有其他的用途,比如可以用來作為配置文件的讀寫模塊,簡單的文件操作等。
它提供的接口很少,容易掌握,而且大多數(shù)情況下會(huì)使用默認(rèn)的參數(shù)。官方文檔中闡明,默認(rèn)的接口參數(shù)和不進(jìn)行子類化會(huì)有更好的性能體現(xiàn)。下面我們對提供的接口進(jìn)行討論,并且僅展示必須參數(shù),其他關(guān)鍵字參數(shù)將以**kwargs表示;
聯(lián)系到上面的基礎(chǔ)知識(shí),我們可以知道,dump 的過程其實(shí)就是向文件句柄中寫數(shù)據(jù),即對象序列化的過程,需要進(jìn)行編碼,只是編碼的格式不只是 unicode 和 str 的轉(zhuǎn)換,而是更重要的 python 對象類型和 JSON 對象類型之間的轉(zhuǎn)換。同理,load 的過程其實(shí)就是從文件句柄中讀數(shù)據(jù),即反序列化生成對象的過程,需要進(jìn)行解碼,只是解碼的格式不只是 str 和 unicode 的轉(zhuǎn)換,而是更重要的 JSON 對象類型和 python 對象類型之間的轉(zhuǎn)換。
下面是 JSON 對象類型和 Python 對象類型之間的對應(yīng)關(guān)系:
JSON | Python 2 | Python 3 |
---|---|---|
object | dict | dict |
array | list | list |
string | unicode | str |
number (int) | int, long | int |
number (real) | float | float |
true | True | True |
false | False | False |
null | None | None |
下面以一個(gè)例子來結(jié)束本文,例子中附帶注釋:
#coding:utf-8
import simplejson as json
#simplejson.dump(**kwargs)
fp = open('./text.json', 'w+')
json.dump([1,2], fp) ##將 python 數(shù)組進(jìn)行序列化,保存到文件中
fp.seek(0)
print "----dump----\n", u'使用 dump 將 python 數(shù)組對象保存在一個(gè)包含 JSON 格式的文件中,文件內(nèi)容為:\n', fp.read()
print
fp.close()
#simplejson.dumps(**kwargs)
r_dumps = json.dumps({"中國 obj":[1,2], "obj2":[3,4]}) #將 python 字典進(jìn)行序列化,保存到字符串中
print "----dumps----\n", u'使用 dumps 將 python 字典對象轉(zhuǎn)換為一個(gè)包含 JSON 格式的字符串,字符串結(jié)果為:\n', r_dumps
print
#simplejson.load(**kwargs)
#如果 json 文檔格式有錯(cuò)誤,將會(huì)拋出 JSONDecoderError 異常
fp = open('./text.json', 'r')
r_load = json.load(fp) #將文件中的內(nèi)容轉(zhuǎn)換為 python 對象
print "----load----\n", u"使用 load 讀取一個(gè)包含 JSON 數(shù)組格式的文件后,得到一個(gè) python 對象,類型是:", type(r_load)
print
#simplejson.loads(**kwargs)
#如果 json 文檔格式有錯(cuò)誤,將會(huì)拋出 JSONDecoderError 異常
#將字符串中的內(nèi)容轉(zhuǎn)換為一個(gè) python 對象
r_loads = json.loads('''{"programmers":[
{"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"},
{"firstName":"Jason","lastName":"Hunter","email":"bbbb"},
{"firstName":"Elliotte","lastName":"Harold","email":"cccc"}
],
"authors":[
{"firstName":"Isaac","lastName":"Asimov","genre":"sciencefiction"},
{"firstName":"Tad","lastName":"Williams","genre":"fantasy"},
{"firstName":"Frank","lastName":"Peretti","genre":"christianfiction"}
]}''')
print "----loads----\n", u"使用 loads 讀取一個(gè)包含 JSON 字典格式的字符串后,得到一個(gè) python 對象,類型是:", type(r_loads)
print
運(yùn)行之后的結(jié)果顯示:
----dump----
使用 dump 將 python 數(shù)組對象保存在一個(gè)包含 JSON 格式的文件中,文件內(nèi)容為:
[1, 2]
----dumps----
使用 dumps 將 python 字典對象轉(zhuǎn)換為一個(gè)包含 JSON 格式的字符串,字符串結(jié)果為:
{"obj2": [3, 4], "\u4e2d\u56fdobj": [1, 2]}
----load----
使用 load 讀取一個(gè)包含 JSON 數(shù)組格式的文件后,得到一個(gè) python 對象,類型是: <type 'list'>
----loads----
使用 loads 讀取一個(gè)包含 JSON 字典格式的字符串后,得到一個(gè) python 對象,類型是: <type 'dict'>