29 python simplejson 模塊淺談

一、背景知識

  • 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 對像類型之間的對應關係:

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

下面以一個例子來結束本文,例子中附帶註釋:

 #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\'>  
《Python實戰-從菜鳥到大牛的進階之路》