json --- JSON 編碼器與解碼器

原始碼:Lib/json/__init__.py


JSON (JavaScript Object Notation) 是一個輕量化的資料交換格式,在 RFC 7159(其廢棄了 RFC 4627)及 ECMA-404 裡面有詳細說明,它啟發自 JavaScript 的物件字面語法 (object literal syntax)(雖然它並不是 JavaScript 的嚴格子集 [1])。

備註

The term "object" in the context of JSON processing in Python can be ambiguous. All values in Python are objects. In JSON, an object refers to any data wrapped in curly braces, similar to a Python dictionary.

警告

當剖析無法信任來源的 JSON 資料時要小心。一段惡意的 JSON 字串可能會導致解碼器耗費大量 CPU 與記憶體資源。建議限制剖析資料的大小。

此模組為習慣標準函式庫 marshalpickle 模組的使用者提供熟悉的 API。

對基本 Python 物件階層進行編碼:

>>> 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}
>>> from io import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
'["streaming API"]'

改用緊湊型編碼方式:

>>> import json
>>> json.dumps([1, 2, 3, {'4': 5, '6': 7}], separators=(',', ':'))
'[1,2,3,{"4":5,"6":7}]'

美化輸出:

>>> import json
>>> print(json.dumps({'6': 7, '4': 5}, sort_keys=True, indent=4))
{
    "4": 5,
    "6": 7
}

自訂 JSON 物件編碼方式:

>>> import json
>>> def custom_json(obj):
...     if isinstance(obj, complex):
...         return {'__complex__': True, 'real': obj.real, 'imag': obj.imag}
...     raise TypeError(f'Cannot serialize object of {type(obj)}')
...
>>> json.dumps(1 + 2j, default=custom_json)
'{"__complex__": true, "real": 1.0, "imag": 2.0}'

JSON 解碼:

>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
['foo', {'bar': ['baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
'"foo\x08ar'
>>> from io import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
['streaming API']

自訂 JSON 物件解碼方式:

>>> import json
>>> def as_complex(dct):
...     if '__complex__' in dct:
...         return complex(dct['real'], dct['imag'])
...     return dct
...
>>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
...     object_hook=as_complex)
(1+2j)
>>> import decimal
>>> json.loads('1.1', parse_float=decimal.Decimal)
Decimal('1.1')

繼承 JSONEncoder 類別並自行擴充額外的編碼方法:

>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
...     def default(self, obj):
...         if isinstance(obj, complex):
...             return [obj.real, obj.imag]
...         # Let the base class default method raise the TypeError
...         return super().default(obj)
...
>>> json.dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
['[2.0', ', 1.0', ']']

在 shell 使用 json 來驗證和美化印出:

$ echo '{"json":"obj"}' | python -m json
{
    "json": "obj"
}
$ echo '{1.2:3.4}' | python -m json
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

更詳盡的文件請見 命令列介面

備註

JSON 語法是 YAML 1.2 語法的一種子集合。所以如果使用預設的設定的話(準確來說,使用預設的 separators 分隔符設定的話),這個模組的輸出也符合 YAML 1.0 和 1.1 的子集合規範。因此你也可以利用這個模組來當作 YAML 的序列化工具(serializer)。

備註

這個模組的編、解碼器預設會保存輸入與輸出資料的順序關係,除非一開始的輸入本身就是無序的。

基本用法

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)

參考這個 Python-to-JSON 轉換表obj 序列化為符合 JSON 格式的串流,並寫入到 fp (一個支援 .write() 方法的 file-like object

備註

picklemarshal 不同,JSON 不具有二進位分框(binary framed)的協定,因此嘗試重複呼叫 dump() 來序列化多個物件到同一個 fp 裡將導致無效的 JSON 檔案。

參數:
  • obj (object) -- 要被序列化的 Python 物件。

  • fp (file-like object) -- The file-like object obj will be serialized to. The json module always produces str objects, not bytes objects, therefore fp.write() must support str input.

  • skipkeys (bool) -- If True, keys that are not of a basic type (str, int, float, bool, None) will be skipped instead of raising a TypeError. Default False.

  • ensure_ascii (bool) -- If True (the default), the output is guaranteed to have all incoming non-ASCII and non-printable characters escaped. If False, all characters will be outputted as-is, except for the characters that must be escaped: quotation mark, reverse solidus, and the control characters U+0000 through U+001F.

  • check_circular (bool) -- 如為 False,則針對不同容器型別的循環參照 (circular reference) 檢查將會被跳過,若有循環參照則最後將引發 RecursionError(或其他更糟的錯誤)。預設為 True

  • allow_nan (bool) -- 如為 False,則序列化不符合嚴格 JSON 規範的超出範圍 float 值 (nan, inf, -inf) 會引發 ValueError。如為 True(預設值),則將使用它們的 JavaScript 等效表示 (NaN, Infinity, -Infinity)。

  • cls (a JSONEncoder subclass) -- If set, a custom JSON encoder with the default() method overridden, for serializing into custom datatypes. If None (the default), JSONEncoder is used.

  • indent (int | str | None) -- If a positive integer or string, JSON array elements and object members will be pretty-printed with that indent level. A positive integer indents that many spaces per level; a string (such as "\t") is used to indent each level. If zero, negative, or "" (the empty string), only newlines are inserted. If None (the default), the most compact representation is used.

  • separators (tuple | None) -- 一個二元組:(item_separator, key_separator)。如為 None(預設值)則 separators 被預設為 (', ', ': '),否則預設為 (',', ': ')。想要獲得最緊湊的 JSON 表示形式,你可以指定 (',', ':') 來消除空格。

  • default (callable | None) -- A function that is called for objects that can't otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError. If None (the default), TypeError is raised.

  • sort_keys (bool) -- If True, dictionaries will be outputted sorted by key. Default False.

在 3.2 版的變更: 除了整數之外,indent 還允許使用字串作為輸入。

在 3.4 版的變更: 如果 indent 不是 None,則使用 (',', ': ') 作為預設值

在 3.6 版的變更: 所有可選參數現在都是僅限關鍵字參數了。

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

使用此轉換表來將 obj 序列化為 JSON 格式 str。這個引數的作用與 dump() 中的同名引數意義相同。

備註

JSON 鍵/值對中的鍵始終為 str 型別。當字典被轉換為 JSON 時,字典的所有鍵值資料型別都會被強制轉換為字串。因此,如果將字典先轉換為 JSON 格式然後再轉換回字典,則該字典可能不等於原始字典。也就是說,如果字典 x 含有非字串鍵值,則 loads(dumps(x)) != x

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

使用此 JSON-to-Python 轉換表fp 解碼為 Python 物件。

參數:
  • fp (file-like object) -- A .read()-supporting text file or binary file containing the JSON document to be deserialized.

  • cls (a JSONDecoder subclass) -- If set, a custom JSON decoder. Additional keyword arguments to load() will be passed to the constructor of cls. If None (the default), JSONDecoder is used.

  • object_hook (callable | None) -- 如果有設定,會用解碼後的 JSON 物件字面值的結果(一個 dict)來呼叫此函式。此函式的回傳值將用來取代 dict。此功能可用於實作自訂解碼器,例如 JSON-RPC 類別提示。預設為 None

  • object_pairs_hook (callable | None) -- 如果有設定,會用任何 JSON 物件字面值以有序對串列解碼的結果來呼叫此函式。此函式的回傳值將用來取代 dict。此功能可用於實作自訂解碼器。如果也設定了 object_hook,以 object_pairs_hook 優先。預設為 None

  • parse_float (callable | None) -- 如果有設定,會用每個要被解碼的 JSON 浮點數字串來呼叫此函式。如果為 None(預設值),則等同於 float(num_str)。此功能可用於將 JSON 浮點數剖析為自訂資料型別,例如 decimal.Decimal

  • parse_int (callable | None) -- 如果有設定,會用每個要被解碼的 JSON 整數字串來呼叫此函式。如果為 None(預設值),則等同於 int(num_str)。此功能可用於將 JSON 整數剖析為自訂資料型別,例如 float

  • parse_constant (callable | None) -- 如果有設定,會用以下字串之一來呼叫此函式:'-Infinity''Infinity''NaN'。此功能可用於在遇到無效的 JSON 數字時引發例外。預設為 None

引發:
  • JSONDecodeError -- 當被去序列化的資料不是有效的 JSON 文件時。

  • UnicodeDecodeError -- 當被去序列化的資料不包含 UTF-8、UTF-16 或 UTF-32 編碼資料時。

在 3.1 版的變更:

  • 新增可選的 object_pairs_hook 參數。

  • 遭遇 'null'、'true' 或 'false' 時不再以 parse_constant 給定的函式來處理了。

在 3.6 版的變更: