python 歷險記(四)— python 中經常使用的 json 操做

引言

你必定據說過 JSON 吧。JSON 是當前最經常使用的數據傳輸格式之一,純文本,容易使用,方便閱讀,最重要的是在多個場合都被大量被使用。python

既然 JSON 這麼好,那就讓咱們繼續探險,去掌握 python 中對 JSON 的經常使用操做吧, okay, let's go!編程

基礎知識

莊子曰:「水之積也不厚,則其負大舟也無力。」。要徹底掌握一個知識點,先將這個知識點須要的基礎知識補齊,這樣學的才能牢固。json

下面就是我認爲學習對 JSON 操做前的知識點。若是您對這部分已經瞭然於胸,盡能夠略過這部分,跳到下一節。數組

什麼是 JSON?

Json (Javascript Object Notation) 是一種輕量級的數據交換格式,它基於 Javascript 的對象字面量。儘管它只是 Javascript 的一個子集,但它與語言無關。以現代編程語言編寫的程序,均可以用它來彼此交換數據。它是一種文本格式,人和機器均可以閱讀它。數據結構

—— 《Javascript 語言精粹》編程語言

既然以現代編程語言均可以用它來交換數據,強大的 python 固然也不例外。要更好的使用 JSON 必定要先了解下它的語法。函數

JSON 的語法

JSON 的值分爲 6 種類型,分別是對象,數組,字符串,數字,布爾值 (truefalse )和null。來看一個典型的 JSON 集合,體會下這些類型。學習

{
  "obj": {
    "name": "xxx",
    "address": {
      "country": "china",
      "city": "TianJin"
    }
  },
  "arr_simple": [1, 2, 3, 5],
  "arr_complex": [
    1,
    "a",
    {
      "b": "yyy"
    },
    true,
    null
  ],
  "str": "I am a string",
  "num": 888,
  "booValue": false,
  "nullValue": null
}

看上面代碼, JSON 語法有什麼特色呢?編碼

  1. JSON 字符串必須使用 雙引號包圍
  2. 能夠在任何值先後插入空白(包括空格,製表符,回車,換行),固然這些空白符也能夠去除。

像字符串,數字,布爾值,null 都比較簡單,無需細數,接下來咱們重點來看下對象和數組。

JSON 對象有哪些特色?

JSON 對象的結構是什麼樣子呢?

上面代碼中的 obj 就是一個 JSON 對象,咱們來觀察下它。

  1. 它是用 {} 括起來的一個集合,每一項都包含名稱 ,如 name 就是名稱,而值就是 xxx
  2. 名稱能夠是任意字符串,但必須是字符串才能夠哦。
  3. 值只要是上面 6 種類型之一就能夠
  4. 名稱/值 對沒有固定的順序,能夠是任意順序
  5. 能夠支持無限層的嵌套,如 obj 對象中嵌套了一個 address 對象,可是爲了保證處理的高效性,請儘可能保持結構的扁平性,也就是不要嵌套太多層哦)

爲了可以處理 JSON 數據,許多語言都有對應的數據類型能夠映射爲 JSON 對象,那麼 python 中是什麼數據類型呢?

dict ,若是有您對 dict 有些遺忘了,就請到這裏複習下吧。

JSON 數組有哪些特色?

上面代碼中的 arr_simplearr_complex 都表示數組,它們有哪些特色呢?

  • 是一個 有序序列
  • 只有 組成
  • 值能夠是任意類型的 JSON 值,如 arr_complex 數組。

python 也有可以映射爲 JSON 對象的數據類型,是 listtuple , 若是您對 listtuple 的特性有些生疏了,也能夠在這裏回顧下。

什麼是編碼和解碼?

說到 JSON 和 python 之間的轉換,就會涉及到兩個名詞:編碼解碼

那麼到底什麼是編碼和解碼呢?

編碼信息從一種形式格式轉換爲另外一種形式的過程。解碼,是編碼的逆過程,亦即把編碼過的信息恢復成原來樣式。

——維基百科

編碼的做用則是爲了利於傳輸和存儲,JSON 固然是很是適合的。所以,

  • 把 python 對象轉換成 JSON 的過程就稱爲編碼
  • 把 JSON 轉換成 python 對象的過程就稱爲解碼

經常使用的 json 操做有哪些?

剛開始接觸 json 的操做,我主要有下面幾個疑問:

  • json 操做須要什麼庫?
  • 如何將 python 對象轉換成 JSON字符串,更進一步,能不能直接轉換成文件句柄存儲到文件中?(編碼)
  • 如何將 json 字符串轉換成 python 對象,更進一步,能不能直接將 JSON 格式的文件轉換成 python 對象?(解碼)

下面就讓咱們一一來探索這些問題。

json 操做須要什麼庫?

使用 json 函數前須要先導入 json 庫:

import json

json 庫自己就是 python 內置的標準庫,所以你不須要作任何安裝的操做。只要聲明瞭上面語句,就可直接使用。

如何將 python 編碼成 JSON?

python 編碼爲 JSON 的對照表

要完成這個功能,先要看下 python 數據結構編碼爲 json 的對照表。

Python JSON
dict object
list, tuple array
str string
int, float, int- & float-derived Enums number
True true
False false
None null

有了這張表,咱們就能夠清楚的知道 python 對象將編碼成的 json 格式。

json.dumps()

json.dumps() 方法的做用就是將 python 對象轉換成 JSON 字符串,下面來看具體的函數聲明:

json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding="utf-8", default=None, sort_keys=False, **kw)

參數看起來好多啊,不過不用擔憂,這麼多參數,只有第一個參數是必填的。下面就來一一瞭解下這些參數的意義

  • obj 就是要編碼的 python 對象
  • skipkeys 默認值是 False。設置爲 True ,假如 obj 中的 dict keys 不是基本類型(str , int , float , bool , None ), 就會被忽略,而不是拋出 TypeError 錯誤
  • ensure_ascii 默認是 True , 表示默認使用ascii 編碼。若是 obj 內含有非 ASCII 字符,就會出現 "\uXXXX" 格式顯式的數據, 設置成 False 就會使用字符原本的編碼。
    • 這裏要注意,若是輸入是中文,須要指定 ensure_ascii=False
  • check_circular 默認值是 True,若是設置爲 False 就不會檢查內部類型是否包含循環引用,並且循環引用會致使 OverflowError
  • allow_nan 默認值爲 False ,若是碰到超過範圍的 float 值(nan, inf, -inf )就使用 (NaN,Infinity, -Infinity) 替換
    • 若是爲 True 碰到這些值則會致使 ValueError
  • indent 縮進設置
    • 若是是非負整數或者 string, JSON Array 元素和對象元素將會按照設置的縮進格式化顯示
    • 值爲 0, 負值,或者 "" 只會插入新的一行
    • 值爲 None (也是默認值)會盡量的壓縮
  • separators 分隔符。
    • 若是要設置它,參數須要是一個元組(item_separator, key_separator)
    • 默認值是 (', ', ': ') ,表示 keys 之間用 , 隔開,而 key 和 value 之間用 : 隔開
  • sort_keys 默認值是 False ,若是設置成 True , dict 結構的輸出就會按照 key 來排序
  • encoding 默認值是 UTF-8 用於設置 JSON 數據的編碼方式,在處理中文時這裏必定要注意。

來看一個例子

>>> import json
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'
>>> print(json.dumps("\"foo\bar"))
"\"foo\bar"
>>> print(json.dumps('\u1234'))
"\u1234"
>>> print(json.dumps('\\'))
"\\"
>>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
{"a": 0, "b": 0, "c": 0}

json.dump()

json.dump() 函數的做用就是將 python 對象轉換成 JSON 字符串,並將其經過 fp 文件流寫入到文件中。來看下具體的函數聲明:

json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

和前面的 dumps 函數進行比較,會發現兩個函數的參數是很是類似的,並且它們的意義也都相同。來看下面的例子

>>> import json
>>> from io import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
'["streaming API"]'

如何將 JSON 解碼成 python 對象?

JSON 解碼爲 python 的對照表

要完成這個功能,也先要看下 json 解碼爲 python 對象的對照表

JSON Python
object dict
array list
string str
number (int) int
number (real) float
true True
false False
null None

編碼對照表和解碼對照表並非一一對應的,所以若是一個 python對象 先編碼成 JSON,再轉碼回來後獲得的對象可就不必定徹底相等了。

json.loads()

這個方法的做用就是將參數 s 按照上面的對照表反序列化爲一個 python 對象。參數 s 能夠是 str ,byte 或者byteArray 格式, 但必需要包含 JSON 文本才能夠)。具體函數聲明以下:

json.loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

下面就來一一瞭解下一些經常使用參數的意義

  • s 就是要解碼的 python 字符串
  • encoding 指定編碼格式
  • parse_float ,默認狀況下至關於 float(num_str)。若是設置爲其餘值,將會把一個 JSON 字符串按照 float 解碼調用,
  • parse_int ,默認狀況下至關於 int(num_str),若是指定,將把每一個 JSON 字符串按照 int 解碼調用

來看下面的例子,其中最後一行就指定了 parse_float

>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
['foo', {'bar': ['baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
'"foo\x08ar'
>>> import decimal
>>> json.loads('1.1', parse_float=decimal.Decimal)
Decimal('1.1')

json.load()

先來看函數聲明

json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

做用是將 fp 文件流反序列化爲 python 對象,其中的參數意義和 loads 方法相同。來看一個例子。

>>> import json
>>> from io import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
['streaming API']

結語

本文主要介紹了 JSON 的定義,語法以及 JSON 的經常使用操做。可是並無涉及 JSON 處理自定義數據類型的高級內容(JSONEncoderJSONDecoder),這部份內容會再後面的篇章中專門介紹。

下篇會介紹 python 的模塊,敬請期待。

參考文檔

  1. python json API Library
  2. 《Javascript 語言精粹》
  3. 編碼—維基百科

相關文章列表

相關文章
相關標籤/搜索