一、背景知識
- JSON:
引用百科描述如下,具體請自行搜索相關介紹:
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它基於 JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一個子集。 JSON 採用完全獨立於語言的文本格式,但是也使用了類似於C語言家族的習慣(包括 C, C++, C#, Java, JavaScript, Perl, Python 等)。這些特性使 JSON 成為理想的數據交換語言。易於人閱讀和編寫,同時也易於機器解析和生成(網絡傳輸速度快)。
表示方法:
- 數據在名稱/值對中
- 數據由逗號分隔
- 花括號保存對像
- 方括號保存數組
示例:
{"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"}]}
- HOWTO-UNICODE:
unicode 標準描述了字符如何對應編碼點(code point),使用 16 進製表示 00 00.
PYTHON 中,basestring 派生了 unicode 類型和 str 類型
unicode 字符串是一個編碼點序列,該序列在內存中會被表示成一組字節(0-255),str 是指 8 字節流。
unicode 字符串可以通過 encode 函數轉換為 str;str 可以通過 decode 轉換為 unicode。編解碼類型一般是 utf-8
示例:
>>> u"中國".encode(\'utf-8\')\'xe4xb8xadxe5x9bxbd\' #將 unicode 字符串編碼為 str>>> \'xe4xb8xadxe5x9bxbd\'.decode(\'utf-8\')u\'u4e2du56fd\' #將 str 解碼為 unicode 字符串
從文件中讀和寫入文件的操作都應該是操作的 8 位字節流,如果將 unicode 字符串寫入文件,需要進行編碼操作;如果從文件中讀 unicode 字符串,首先讀取出來的是 8 位字節流需要進行解碼操作。
一般功能代碼中都直接操作 unicode 字符串,而只在寫數據或讀數據時添加對應的編解碼操作。
- 序列化和反序列化
當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進制序列的形式在網絡上傳送。發送方需要把這個對象轉換為字節序列,才能在網絡上傳送;接收方則需要把字節序列再恢復為對象。
把對像轉換為字節序列的過程稱為對象的序列化,比如把一個字典對像以某種格式(JSON)寫到文件中;把字節序列恢復為對象的過程稱為對象的反序列化,比如讀取某種格式化(JSON)的文件,構造一個字典對象。
根據 HOWTO-UNICODE 的知識,把網絡可以看做是一個文件,發送方寫數據到網絡時需要進行編碼,接收方讀取數據時需要進行解碼。也就是說序列化的同時會進行編碼,反序列化的同時會進行解碼。
二、simplejson
simplejson 是 json 標準模塊的擴展(基礎功能相同),是 pypi 提供的拓展模塊,需要另行安裝。不過可以使用 python 自帶的 json 庫,基本是相同的使用方法(提供的接口功能基本一致)。在 python 的 library 文檔中將 JSON 歸為網絡數據控制類,很好的說明了他們的用途,主要用於網絡數據控制,編解碼等。但是也具有其他的用途,比如可以用來作為配置文件的讀寫模塊,簡單的文件操作等。
它提供的接口很少,容易掌握,而且大多數情況下會使用默認的參數。官方文檔中闡明,默認的接口參數和不進行子類化會有更好的性能體現。下面我們對提供的接口進行討論,並且僅展示必須參數,其他關鍵字參數將以**kwargs表示;
- simplejson.dump(obj, fp, **kwargs):將 python 對像寫到文件中(以 JSON 格式)
- simplejson.dumps(obj, **kwargs):將 python 對像表示成字符串(JSON 的格式)
- simplejson.load(fp, **kwargs):從文件中(包含 JSON 結構)讀取為 python 對像
- simplejson.loads(s, **kwargs):從字符串中(包含 JSON 結構)讀取為 python 對像
- class simplejson.JSONDecoder:load/loads 的時候調用,將 JSON 格式序列解碼為 python 對像
- class simplejson.JSONEncoder:dump/dumps 的時候調用,將 python 對像編碼為 JSON 格式序列
聯繫到上面的基礎知識,我們可以知道, dump 的過程其實就是向文件句柄中寫數據,即對像序列化的過程,需要進行編碼,只是編碼的格式不只是 unicode 和 str 的轉換,而是更重要的 python 對像類型和 JSON 對像類型之間的轉換。同理,load 的過程其實就是從文件句柄中讀數據,即反序列化生成對象的過程,需要進行解碼,只是解碼的格式不只是 str 和 unicode 的轉換,而是更重要的 JSON 對像類型和 python 對像類型之間的轉換。
下面是 JSON 對像類型和 Python 對像類型之間的對應關係:
下面以一個例子來結束本文,例子中附帶註釋:
#coding:utf-8import simplejson as json #simplejson.dump(**kwargs)fp = open(\'./text.json\', \'w+\')json.dump([1,2], fp) ##將 python 數組進行序列化,保存到文件中fp.seek(0)print "----dump----n", u\'使用 dump 將 python 數組對像保存在一個包含 JSON 格式的文件中,文件內容為:n\', fp.readprint fp.close #simplejson.dumps(**kwargs)r_dumps = json.dumps({"中國 obj":[1,2], "obj2":[3,4]}) #將 python 字典進行序列化,保存到字符串中print "----dumps----n", u\'使用 dumps 將 python 字典對像轉換為一個包含 JSON 格式的字符串,字符串結果為:n\', r_dumpsprint #simplejson.load(**kwargs) #如果 json 文檔格式有錯誤,將會拋出 JSONDecoderError 異常fp = open(\'./text.json\', \'r\')r_load = json.load(fp) #將文件中的內容轉換為 python 對像print "----load----n", u"使用 load 讀取一個包含 JSON 數組格式的文件後,得到一個 python 對象,類型是:", type(r_load)print #simplejson.loads(**kwargs) #如果 json 文檔格式有錯誤,將會拋出 JSONDecoderError 異常 #將字符串中的內容轉換為一個 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 讀取一個包含 JSON 字典格式的字符串後,得到一個 python 對象,類型是:", type(r_loads)print
運行之後的結果顯示:
----dump----使用 dump 將 python 數組對像保存在一個包含 JSON 格式的文件中,文件內容為:[1, 2]----dumps----使用 dumps 將 python 字典對像轉換為一個包含 JSON 格式的字符串,字符串結果為:{"obj2": [3, 4], "u4e2du56fdobj": [1, 2]}----load----使用 load 讀取一個包含 JSON 數組格式的文件後,得到一個 python 對象,類型是: <type \'list\'>----loads----使用 loads 讀取一個包含 JSON 字典格式的字符串後,得到一個 python 對象,類型是: <type \'dict\'>