29 python simplejson 模塊淺談
Python實戰-從菜鳥到大牛的進階之路 作者:極客學院 投票推薦 加入書簽 留言反饋
一、背景知識<ul><li>json:</li></ul>
引用百科描述如下,具體請自行搜索相關介紹:
json(javascript object notation) 是一種輕量級的數據交換格式。它基於 javascript(standard ecma-262 3rd edition - december 1999)的一個子集。 json 采用完全獨立於語言的文本格式,但是也使用了類似於c語言家族的習慣(包括 c, c++, c#, java, javascript, perl, python 等)。這些特性使 json 成為理想的數據交換語言。易於人閱讀和編寫,同時也易於機器解析和生成(網絡傳輸速度快)。
表示方法: <ul><li>數據在名稱/值對中</li><li>數據由逗號分隔</li><li>花括號保存對象</li><li>方括號保存數組</li></ul>
示例:
{"programmers":[{"firstname":"brett","stname":"mughlin","email":"aaaa"},{"firstname":"jason","stname":"hunter","email":"bbbb"},{"firstname":"elliotte","stname":"harold","email":"cc"}],"authors":[{"firstname":"isaac","stname":"asimov","genre":"sciencefiction"},{"firstname":"tad","stname":"williams","genre":"fantasy"},{"firstname":"frank","stname":"peretti","genre":"christianfiction"}]} </pre><ul><li>howto-unicode:</li></ul>
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 字符串 </pre>
從文件中讀和寫入文件的操作都應該是操作的 8 位字節流,如果將 unicode 字符串寫入文件,需要進行編碼操作;如果從文件中讀 unicode 字符串,首先讀取出來的是 8 位字節流需要進行解碼操作。
一般功能代碼中都直接操作 unicode 字符串,而隻在寫數據或讀數據時添加對應的編解碼操作。 <ul><li>序列化和反序列化</li></ul>
當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進製序列的形式在網絡上傳送。發送方需要把這個對象轉換為字節序列,才能在網絡上傳送;接收方則需要把字節序列再恢複為對象。
把對象轉換為字節序列的過程稱為對象的序列化,比如把一個字典對象以某種格式(json)寫到文件中;把字節序列恢複為對象的過程稱為對象的反序列化,比如讀取某種格式化(json)的文件,構造一個字典對象。
根據 howto-unicode 的知識,把網絡可以看做是一個文件,發送方寫數據到網絡時需要進行編碼,接收方讀取數據時需要進行解碼。也就是說序列化的同時會進行編碼,反序列化的同時會進行解碼。
二、simplejson
simplejson 是 json 標準模塊的擴展(基礎功能相同),是 pypi 提供的拓展模塊,需要另行安裝。不過可以使用 python 自帶的 json 庫,基本是相同的使用方法(提供的接口功能基本一致)。在 python 的 library 文檔中將 json 歸為網絡數據控製類,很好的說明了他們的用途,主要用於網絡數據控製,編解碼等。但是也具有其他的用途,比如可以用來作為配置文件的讀寫模塊,簡單的文件操作等。
它提供的接口很少,容易掌握,而且大多數情況下會使用默認的參數。官方文檔中闡明,默認的接口參數和不進行子類化會有更好的性能體現。下麵我們對提供的接口進行討論,並且僅展示必須參數,其他關鍵字參數將以**kwargs表示; <ul><li>simplejson.dump(obj, fp, **kwargs):將 python 對象寫到文件中(以 json 格式)</li><li>simplejson.dumps(obj, **kwargs):將 python 對象表示成字符串(json 的格式)</li><li>simplejson.load(fp, **kwargs):從文件中(包含 json 結構)讀取為 python 對象</li><li>simplejson.loads(s, **kwargs):從字符串中(包含 json 結構)讀取為 python 對象</li><li>ss simplejson.jsondecoder:load/loads 的時候調用,將 json 格式序列解碼為 python 對象</li><li>ss simplejson.jsonencoder:dump/dumps 的時候調用,將 python 對象編碼為 json 格式序列</li></ul>
聯係到上麵的基礎知識,我們可以知道, dump 的過程其實就是向文件句柄中寫數據,即對象序列化的過程,需要進行編碼,隻是編碼的格式不隻是 unicode 和 str 的轉換,而是更重要的 python 對象類型和 json 對象類型之間的轉換。同理,load 的過程其實就是從文件句柄中讀數據,即反序列化生成對象的過程,需要進行解碼,隻是解碼的格式不隻是 str 和 unicode 的轉換,而是更重要的 json 對象類型和 python 對象類型之間的轉換。
下麵是 json 對象類型和 python 對象類型之間的對應關係: <thead> <th >json</th> <th >python 2</th> <th >python 3</th></thead> 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","stname":"mughlin","email":"aaaa"},{"firstname":"jason","stname":"hunter","email":"bbbb"},{"firstname":"elliotte","stname":"harold","email":"cc"}],"authors":[{"firstname":"isaac","stname":"asimov","genre":"sciencefiction"},{"firstname":"tad","stname":"williams","genre":"fantasy"},{"firstname":"frank","stname":"peretti","genre":"christianfiction"}]}\''\''\'')print "----loads----n", u"使用 loads 讀取一個包含 json 字典格式的字符串後,得到一個 python 對象,類型是:", type(r_loads)print </pre>
運行之後的結果顯示:
----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\''> </pre>
引用百科描述如下,具體請自行搜索相關介紹:
json(javascript object notation) 是一種輕量級的數據交換格式。它基於 javascript(standard ecma-262 3rd edition - december 1999)的一個子集。 json 采用完全獨立於語言的文本格式,但是也使用了類似於c語言家族的習慣(包括 c, c++, c#, java, javascript, perl, python 等)。這些特性使 json 成為理想的數據交換語言。易於人閱讀和編寫,同時也易於機器解析和生成(網絡傳輸速度快)。
表示方法: <ul><li>數據在名稱/值對中</li><li>數據由逗號分隔</li><li>花括號保存對象</li><li>方括號保存數組</li></ul>
示例:
{"programmers":[{"firstname":"brett","stname":"mughlin","email":"aaaa"},{"firstname":"jason","stname":"hunter","email":"bbbb"},{"firstname":"elliotte","stname":"harold","email":"cc"}],"authors":[{"firstname":"isaac","stname":"asimov","genre":"sciencefiction"},{"firstname":"tad","stname":"williams","genre":"fantasy"},{"firstname":"frank","stname":"peretti","genre":"christianfiction"}]} </pre><ul><li>howto-unicode:</li></ul>
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 字符串 </pre>
從文件中讀和寫入文件的操作都應該是操作的 8 位字節流,如果將 unicode 字符串寫入文件,需要進行編碼操作;如果從文件中讀 unicode 字符串,首先讀取出來的是 8 位字節流需要進行解碼操作。
一般功能代碼中都直接操作 unicode 字符串,而隻在寫數據或讀數據時添加對應的編解碼操作。 <ul><li>序列化和反序列化</li></ul>
當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進製序列的形式在網絡上傳送。發送方需要把這個對象轉換為字節序列,才能在網絡上傳送;接收方則需要把字節序列再恢複為對象。
把對象轉換為字節序列的過程稱為對象的序列化,比如把一個字典對象以某種格式(json)寫到文件中;把字節序列恢複為對象的過程稱為對象的反序列化,比如讀取某種格式化(json)的文件,構造一個字典對象。
根據 howto-unicode 的知識,把網絡可以看做是一個文件,發送方寫數據到網絡時需要進行編碼,接收方讀取數據時需要進行解碼。也就是說序列化的同時會進行編碼,反序列化的同時會進行解碼。
二、simplejson
simplejson 是 json 標準模塊的擴展(基礎功能相同),是 pypi 提供的拓展模塊,需要另行安裝。不過可以使用 python 自帶的 json 庫,基本是相同的使用方法(提供的接口功能基本一致)。在 python 的 library 文檔中將 json 歸為網絡數據控製類,很好的說明了他們的用途,主要用於網絡數據控製,編解碼等。但是也具有其他的用途,比如可以用來作為配置文件的讀寫模塊,簡單的文件操作等。
它提供的接口很少,容易掌握,而且大多數情況下會使用默認的參數。官方文檔中闡明,默認的接口參數和不進行子類化會有更好的性能體現。下麵我們對提供的接口進行討論,並且僅展示必須參數,其他關鍵字參數將以**kwargs表示; <ul><li>simplejson.dump(obj, fp, **kwargs):將 python 對象寫到文件中(以 json 格式)</li><li>simplejson.dumps(obj, **kwargs):將 python 對象表示成字符串(json 的格式)</li><li>simplejson.load(fp, **kwargs):從文件中(包含 json 結構)讀取為 python 對象</li><li>simplejson.loads(s, **kwargs):從字符串中(包含 json 結構)讀取為 python 對象</li><li>ss simplejson.jsondecoder:load/loads 的時候調用,將 json 格式序列解碼為 python 對象</li><li>ss simplejson.jsonencoder:dump/dumps 的時候調用,將 python 對象編碼為 json 格式序列</li></ul>
聯係到上麵的基礎知識,我們可以知道, dump 的過程其實就是向文件句柄中寫數據,即對象序列化的過程,需要進行編碼,隻是編碼的格式不隻是 unicode 和 str 的轉換,而是更重要的 python 對象類型和 json 對象類型之間的轉換。同理,load 的過程其實就是從文件句柄中讀數據,即反序列化生成對象的過程,需要進行解碼,隻是解碼的格式不隻是 str 和 unicode 的轉換,而是更重要的 json 對象類型和 python 對象類型之間的轉換。
下麵是 json 對象類型和 python 對象類型之間的對應關係: <thead> <th >json</th> <th >python 2</th> <th >python 3</th></thead> 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","stname":"mughlin","email":"aaaa"},{"firstname":"jason","stname":"hunter","email":"bbbb"},{"firstname":"elliotte","stname":"harold","email":"cc"}],"authors":[{"firstname":"isaac","stname":"asimov","genre":"sciencefiction"},{"firstname":"tad","stname":"williams","genre":"fantasy"},{"firstname":"frank","stname":"peretti","genre":"christianfiction"}]}\''\''\'')print "----loads----n", u"使用 loads 讀取一個包含 json 字典格式的字符串後,得到一個 python 對象,類型是:", type(r_loads)print </pre>
運行之後的結果顯示:
----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\''> </pre>