"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 與記憶體資源。建議限制剖析資料的大小。

此模組為習慣標準函式庫 "marshal" 與 "pickle" 模組的使用者提供熟悉的
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*）

   備註:

     與 "pickle" 和 "marshal" 不同，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), no newlines are inserted.

      * **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, array_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"。

      * **array_hook** (*callable* | None) -- If set, a function that
        is called with the result of any JSON array literal decoded
        with as a Python list. The return value of this function will
        be used instead of the "list". This feature can be used to
        implement custom decoders. Default "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 版的變更:

   * 所有可選參數現在都是僅限關鍵字參數了。

   * 現在，*fp* 可以是一個*二進位檔案*，前提是其編碼格式為 UTF-8、
     UTF-16 或 UTF-32。

   在 3.11 版的變更: 預設 *parse_int* 使用的 "int()" 函式現在有限制整
   數字串的長度上限了，限制由直譯器的整數字串轉換長度限制機制來達成，
   這能防止阻斷服務攻擊 (Denial of Service attacks)。

   在 3.15 版的變更: Added the optional *array_hook* parameter.

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

   與 "load()" 相同，但不是類檔案物件，而是使用轉換表將 *s*（一個包含
   JSON 文件的 "str"、"bytes" 或 "bytearray" 實例）去序列化為 Python
   物件。

   在 3.6 版的變更: 現在，*s* 可以是一個二進位檔案如 "bytes" 或
   "bytearray"，前提是其編碼格式為 UTF-8、UTF-16 或 UTF-32。

   在 3.9 版的變更: 刪除關鍵字引數 *encoding*。


編碼器與解碼器
==============

class json.JSONDecoder(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None, array_hook=None)

   簡易 JSON 解碼器

   預設將執行下列資料型別轉換：

   +-----------------+---------------------+
   | JSON            | Python              |
   |=================|=====================|
   | object          | dict                |
   +-----------------+---------------------+
   | array           | list                |
   +-----------------+---------------------+
   | string          | str                 |
   +-----------------+---------------------+
   | number (整數)   | int                 |
   +-----------------+---------------------+
   | number (實數)   | float               |
   +-----------------+---------------------+
   | true            | True                |
   +-----------------+---------------------+
   | false           | False               |
   +-----------------+---------------------+
   | null            | None                |
   +-----------------+---------------------+

   雖然 "NaN"、"Infinity" 和 "-Infinity" 並不符合 JSON 規範，但解碼器
   依然能正確地將其轉換到相應的 Python "float" 值。

   *object_hook* 是一個可選函式，其接受一個解碼後的 JSON 物件作為輸入
   ，並使用其回傳值來取代原先的 "dict"。這個功能可用於提供自訂的去序列
   化（例如支援 JSON-RPC 類別提示）。

   *object_pairs_hook* is an optional function that will be called
   with the result of every JSON object decoded with an ordered list
   of pairs.  The return value of *object_pairs_hook* will be used
   instead of the "dict".  This feature can be used to implement
   custom decoders.  If *object_hook* is also defined, the
   *object_pairs_hook* takes priority.

   在 3.1 版的變更: 新增對於 *object_pairs_hook* 的支援。

   *array_hook* is an optional function that will be called with the
   result of every JSON array decoded as a list. The return value of
   *array_hook* will be used instead of the "list". This feature can
   be used to implement custom decoders.

   在 3.15 版的變更: Added support for *array_hook*.

   *parse_float* 為可選函式，每個要被解碼的 JSON 浮點數字串都會改用這
   個參數給定的函式來進行解碼。預設情況這等效於 "float(num_str)"。這個
   參數可用於將 JSON 中的浮點數解碼或剖析為另一種資料型別（例如
   "decimal.Decimal"）。

   *parse_int* 為可選函式，當解碼 JSON 整數字串時會被呼叫。預設情況等
   效於 "int(num_str)"。這個參數可用於將 JSON 中的整數解碼或剖析為另一
   種資料型別（例如 "float"）。

   *parse_constant* 為可選函式，在解碼時若遭遇字串 "'-Infinity'"、
   "'Infinity'" 或 "'NaN'" 其中之一則會改用這個參數給定的函式來進行解
   碼。這也可用於使解碼過程中遇到無效的 JSON 數字時引發一個例外。

   如果 *strict* 被設為 false（預設值為 "True"），那麼字串中將允許控制
   字元。此語境中的控制字元指的是 ASCII 字元編碼在 0～31 範圍內的字元
   ，包括 "'\t'``（tab）、"'n'"、"'r'`` 和 "'\0'"。

   如果被去序列化（deserialized）的資料不符合 JSON 格式，將會引發
   "JSONDecodeError" 例外。

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

   decode(s)

      回傳用 Python 型式表達的 *s* （一個含有 JSON 文件的 "str" 實例）
      。

      若給定的輸入不符合 JSON 格式會引發 "JSONDecodeError" 例外。

   raw_decode(s)

      將 *s* （一個開頭部分含有合格 JSON 文件的 "str"） 解碼，並將
      JSON 文件結束點的索引值（index）和解碼結果合併為一個二元組（
      2-tuple）後回傳。

      這個方法可以用來解碼尾段可能帶有 JSON 以外資料的文字。

class json.JSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)

   可擴充的 Python 資料結構 JSON 編碼器。

   預設可支援下列物件及型別：

   +------------------------------------------+-----------------+
   | Python                                   | JSON            |
   |==========================================|=================|
   | dict                                     | object          |
   +------------------------------------------+-----------------+
   | list, tuple                              | array           |
   +------------------------------------------+-----------------+
   | str                                      | string          |
   +------------------------------------------+-----------------+
   | int、float 或可作為整數或浮點數運算的衍  | number          |
   | 生列舉（int- or float- derived Enums）   |                 |
   +------------------------------------------+-----------------+
   | True                                     | true            |
   +------------------------------------------+-----------------+
   | False                                    | false           |
   +------------------------------------------+-----------------+
   | None                                     | null            |
   +------------------------------------------+-----------------+

   在 3.4 版的變更: 增加對整數（int）、浮點數（float）或可作為整數或浮
   點數運算的衍生列舉（int- or float-derived Enums）類別的支援性。

   若要擴充此功能來識別其他物件，請繼承並實作一個 "default()" 方法。此
   方法應回傳一個可序列化的 "o" 物件，否則此方法應呼叫父類別的
   JSONEncoder.default 方法（以引發 "TypeError" 例外）。

   若 *skipkeys* 為 false（預設值），則當在編碼不是 "str"、"int"、
   "float"、"bool" 或 "None" 的鍵值時，將引發 "TypeError"。如果
   *skipkeys* 為 true，這些項目將直接被跳過。

   如果 *ensure_ascii* 為 true（預設值），則輸出將保證所有非 ASCII 和
   非可列印字元都會被跳脫。如果 *ensure_ascii* 為 false，則所有字元都
   將按原樣輸出，唯有必須跳脫的字元例外：引號、反斜線，以及控制字元
   U+0000 到 U+001F。

   如果 *check_circular* 為 true（預設值），則會在編碼期間檢查串列（
   list）、字典（dict）和自訂編碼物件的循環參照，以防止無限遞迴（一個
   會導致 "RecursionError" 例外的問題）。否則不會進行此類檢查。

   如果 *allow_nan* 為 true（預設值），則 "NaN"、"Infinity" 和
   "-Infinity" 將按照原樣進行編碼。請記得此行為不符合標準 JSON 規範，
   但的確與大多數基於 JavaScript 的編碼器和解碼器一致。否則若設為
   false，嘗試對這些浮點數進行編碼將引發 "ValueError" 例外。

   如果 *sort_keys* 為 true（預設值："False"），則 dictionary（字典）
   的輸出將按鍵值排序。這項功能可確保 JSON 序列化的結果能被互相比較，
   能讓日常的回歸測試檢查變得方便一些。

   如果 *indent* 是非負整數或字串，則 JSON 陣列元素和物件成員將使用該
   縮排等級進行格式美化。縮排等級 0、負數或 """" 只會插入換行符號。
   "None"（預設值）等於是選擇最緊湊的表示法。使用正整數縮排可以在每層
   縮排數量相同的空格。如果 *indent* 是一個字串（例如 ""\t""），則該字
   串用於縮排每個層級。

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

   如果有指定本引數內容，*separators* 應該是一個 "(item_separator,
   key_separator)" 二元組。如果 *indent* 為 "None" 則預設為 "(', ', ':
   ')"，否則預設為 "(',', ': ')"。想要獲得最緊湊的 JSON 表示形式，你可
   以改成指定 "(',', ':')" 來消除空格。

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

   如果有指定本參數，*default* 會是一個遭遇無法序列化的物件時會被呼叫
   的函式。它應該回傳該物件的 JSON 可編碼版本或引發 "TypeError"。如果
   未指定，則會直接引發 "TypeError"。

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

   default(o)

      在任意一個子類別裡實作這個方法時須讓其回傳一個可序列化的物件 *o*
      ，或呼叫原始的實作以引發 "TypeError" 例外。

      舉例來說，想要讓編碼器支援任意疊代器（iterator），你可以實作這樣
      子的 "default()"：

         def default(self, o):
            try:
                iterable = iter(o)
            except TypeError:
                pass
            else:
                return list(iterable)
            # 讓基底類別的預設方法引發 TypeError
            return super().default(o)

   encode(o)

      回傳一個 Python 資料結構物件 *o* 的 JSON 的字串表示。例如：

         >>> json.JSONEncoder().encode({"foo": ["bar", "baz"]})
         '{"foo": ["bar", "baz"]}'

   iterencode(o)

      將物件 *o* 編碼，並將結果統整為一個能依序產生（yield）各結果字串
      的物件。如下例：

         for chunk in json.JSONEncoder().iterencode(bigobject):
             mysocket.write(chunk)


例外
====

exception json.JSONDecodeError(msg, doc, pos)

   "ValueError" 的子類別具有下列額外屬性：

   msg

      未受格式化的錯誤訊息。

   doc

      正在被剖析的 JSON 文件。

   pos

      *doc* 剖析失敗處的起始點的索引值。

   lineno

      *pos* 所在的列（line）數。

   colno

      *pos* 所在的行（column）數。

   在 3.5 版被加入.


合規性與互通性（Interoperability）
==================================

JSON 格式是由 **RFC 7159** 和 ECMA-404 規範的。本節詳細說明了本模組對
RFC 的遵循程度。簡單起見，"JSONEncoder" 和 "JSONDecoder" 子類別以及未
明確提及的參數將不予討論。

這個模組的部份實作並未非常嚴格地遵循 RFC 規範。準確來說，下列實際實作
符合 JavaScript 語法格式，但並不符合 JSON 格式：

* 無限（Infinite）和非數字（NaN）值會被接受。

* 同一個物件內可以有重複的名稱，但只有最後一個同名物件是有效的。

不過 RFC 准許遵循 RFC 的剖析器接受不合規的文字輸入，所以技術上來說若以
預設設定運作，本模組的去序列化器（deserializer）是符合 RFC 規範的。


字元編碼格式
------------

RFC 要求 JSON 必須以 UTF-8、UTF-16 或 UTF-32 格式編碼。並推薦以 UTF-8
編碼以達成最佳的互通性。

RFC 准許但並不強制編碼器預設要設定 *ensure_ascii=True*，因此跳脫輸出使
得結果字串只包含可列印的 ASCII 字元。

除了 *ensure_ascii* 選項參數之外，本模組嚴格遵循 Python 物件與
"Unicode strings" 之間的轉換規範，因此並不另外處理字元編碼的問題。

RFC 禁止在文件的開頭加上端序記號（Byte Order Mark），因此本模組的序列
化器（serializer）也不會在輸出中加入端序記號。RFC 允許但不強制 JSON 去
序列化器（deserializer）忽略文件初始的端序記號，因此本模組的去序列化器
將在遭遇位於文件開頭的端序記號時引發 "ValueError" 例外。

RFC 並未明確禁止 JSON 文件包含無法對應有效 Unicode 字元的位元組序列（
例如未配對的 UTF-16 代理對（surrogate pairs）），但這個特性的確可能會
引起相容性問題。預設情況下，當原始輸入的 "str" 中存在此類序列時，該模
組將接受並輸出這些序列的編碼位置（code points）。


正負無限與非數值
----------------

RFC 不允許表現無限大或非數值（NaN）。但預設情況下，這個模組仍接受並輸
出 "Infinity"、"-Infinity" 和 "NaN"，如同它們是有效的 JSON 數值字面值
：

   >>> # Neither of these calls raises an exception, but the results are not valid JSON
   >>> json.dumps(float('-inf'))
   '-Infinity'
   >>> json.dumps(float('nan'))
   'NaN'
   >>> # Same when deserializing
   >>> json.loads('-Infinity')
   -inf
   >>> json.loads('NaN')
   nan

在序列化器中，*allow_nan* 參數可以改變這個行為。在去序列化器中，
*parse_constant* 參數可以改變這個行為。


物件內重複的名稱
----------------

RFC 規範僅表明 JSON 物件中的名字應該是唯一的，但沒有強制要求如何處理重
複的名字。預設情況下，本模組不會因此引發例外；相反的，它會忽略該名字的
所有重複鍵值對，並只保留最後一個：

   >>> weird_json = '{"x": 1, "x": 2, "x": 3}'
   >>> json.loads(weird_json)
   {'x': 3}

*object_pairs_hook* 參數可以改變這個行為。


位於頂層的非物件及非列表值
--------------------------

由已廢棄的 **RFC 4627** 所規範的舊版 JSON 要求 JSON 文字的頂層值必須是
JSON 物件或陣列（Python "dict" 或 "list"），而且不能是 JSON 的 null、
boolean、數字或字串值。 **RFC 7159** 移除了這個限制，而本模組的序列化
器或去串列化器中未曾實施過該限制。

如果想要最大限度地保留互通性，你可能還是會想要自行施加這個限制。


實作限制
--------

某些 JSON 去序列化器的實作可能會造成下列限制：

* JSON 文件長度上限

* JSON 物件或陣列的最大巢狀層數（level of nesting）限制

* 數字的精準度或範圍

* JSON 字串長度上限

本模組除了 Python 資料型別本身或 Python 直譯器本身的限制以外，不會設定
任何此類限制。

將資料序列化為 JSON 時，要注意可能會使用該 JSON 輸出的應用程式中的相關
限制。特別要注意的是，JSON 數字常會被去序列化為 IEEE 754 雙精度浮點數
（double），並因而受到其表示範圍和精度限制的影響。這在序列化極大的
Python "int" 數值、或是序列化特殊數字型別的實例時（例如
"decimal.Decimal"）尤其重要。


命令列介面
==========

**原始碼：**Lib/json/tool.py

======================================================================

The "json" module can be invoked as a script via "python -m json" to
validate and pretty-print JSON objects. The "json.tool" submodule
implements this interface.

如果沒有指定可選引數 "infile" 和 "outfile" ，則 "sys.stdin" 和
"sys.stdout" 將各自做為輸入和輸出的預設值。

   $ 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)

在 3.5 版的變更: 現在開始輸出和輸入的資料順序會是相同的。傳入 "--sort-
keys" 引數以按照鍵值的字母順序對輸出進行排序。

在 3.14 版的變更: The "json" module may now be directly executed as
"python -m json". For backwards compatibility, invoking the CLI as
"python -m json.tool" remains supported.


命令列選項
----------

infile

   將被用於校驗或美化呈現的 JSON 文件：

      $ python -m json mp_films.json
      [
          {
              "title": "And Now for Something Completely Different",
              "year": 1971
          },
          {
              "title": "Monty Python and the Holy Grail",
              "year": 1975
          }
      ]

   如果沒有指定 *infile* 則會從 "sys.stdin" 讀取輸入。

outfile

   將 *infile* 的結果寫入到給定的 *outfile*。若未提供則寫入到
   "sys.stdout"。

--sort-keys

   按照鍵值的字母順序對輸出字典進行排序。

   在 3.5 版被加入.

--no-ensure-ascii

   關閉非 ASCII 字元的自動跳脫功能。詳情請參照 "json.dumps()"。

   在 3.9 版被加入.

--json-lines

   將每一行輸入都單獨輸出為一個 JSON 物件。

   在 3.8 版被加入.

--indent, --tab, --no-indent, --compact

   互斥的空白字元控制選項。

   在 3.9 版被加入.

-h, --help

   顯示說明訊息。

-[ 註解 ]-

[1] 如 RFC 7159 更正 所述，JSON 允許字串中出現 U+2028（列分隔符）和
    U+2029（段落分隔符）字元，而 JavaScript（截至 ECMAScript 5.1 版）
    則不允許。
