"json" --- JSON 编码器和解码器
******************************

**源代码:** Lib/json/__init__.py

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

JSON (JavaScript Object Notation)，由 **RFC 7159** (它取代了 **RFC
4627**) 和 ECMA-404 进行规范，是一个受到 JavaScript 对象字面值语法启发
的轻量级数据交换格式 (虽然它并不是严格意义上的 JavaScript 子集 [1] )。

备注:

  术语"对象"在 Python 语言 JSON 处理的上下文中存在歧义。 Python 中的所
  有值都是对象。 在 JSON 中，对象则是指包裹在花括号里的任何数据，这类
  似于 Python 字典。

警告:

  在解析来自不受信任来源的 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', ']']

Using "json" from the shell to validate and pretty-print:

   $ 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 的一个子集。 由该模块的默认设置所产生的 JSON（尤其
  是默认的 *separators* 值）也是 YAML 1.0 和 1.1 的一个子集。 因此该模
  块也能被用作 YAML 序列化器。

备注:

  这个模块的编码器和解码器默认保持输入和输出的顺序。仅当底层的容器未排
  序时才会失去顺序。


基本使用
========

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 至 JSON 转换表 将 *obj* 序列化为输出到 *fp* (一个支
   持 ".write()" 的 *file-like object*) 的已格式化的 JSON 流。

   备注:

     与 "pickle" 和 "marshal" 不同，JSON 不是一个具有框架的协议，所以
     尝试多次使用同一个 *fp* 调用 "dump()" 来序列化多个对象会产生一个
     不合规的 JSON 文件。

   参数:
      * **obj** (*object*) -- 要序列化的 Python 对象。

      * **fp** (*file-like object*) -- *obj* 将被序列化输出到的文件型
        对象。 "json" 模块总是产生 "str" 对象，而不是 "bytes" 对象，因
        此 "fp.write()" 必须支持 "str" 输入。

      * **skipkeys** (*bool*) -- 如为 "True"，则不为基本类型 ("str",
        "int", "float", "bool", "None") 的键将被跳过而不会引发
        "TypeError"。 默认为 "False"。

      * **ensure_ascii** (*bool*) -- 如果为 "True" (默认值)，输出将确
        保对所有输入的非 ASCII 和不可打印字符进行转义。 如果为 "False"
        ，则所有字符将被原样输出，只有必须被转义的字符除外：引号、反斜
        线，以及 U+0000 至 U+001F 范围的控制字符。

      * **check_circular** (*bool*) -- 如为 "False"，则对容器类型的循
        环引用检查会被跳过并且循环引用将导致 "RecursionError" (或更糟
        的情况)。 默认为 "True"。

      * **allow_nan** (*bool*) -- 如为 "False"，则对超范围的 "float"
        值 ("nan", "inf", "-inf") 进行序列化将导致 "ValueError"，以严
        格遵循 JSON 规范。 如为 "True" (默认值)，则将使用它们的
        JavaScript 等价形式 ("NaN", "Infinity", "-Infinity")。

      * **cls** (a "JSONEncoder" subclass) -- 如果设置，则使用一个重写
        了 "default()" 方法的自定义 JSON 编码器，用以序列化为自定义的
        数据类型。 如为 "None" (默认值)，则使用 "JSONEncoder"。

      * **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" (默认值)，则默
        认当 *indent* 为 "None" 时 *separators* 为 "(', ', ': ')"，否
        则为 "(',', ': ')"。 要使用最紧凑形式的 JSON，可指定 "(',',
        ':')" 来去除空格。

      * **default** (*callable* | None) -- 当对象无法被序列化时将被调
        用的函数。 它应该返回一个可被 JSON 编码的版本或是引发
        "TypeError"。 如为 "None" (默认值)，则会引发 "TypeError"。

      * **sort_keys** (*bool*) -- 如为 "True"，则字典输出将按键排序。
        默认为 "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 至 Python 转换表 将 *fp* 反序列化为 Python 对象。

   参数:
      * **fp** (*file-like object*) -- 一个包含要执行反序列化的 JSON
        文档的支持 ".read()" 的 *text file* 或 *binary file*。

      * **cls** (a "JSONDecoder" subclass) -- 如果设定此参数，则使用自
        定义的JSON解码器。任何传递给 "load()" 方法的多余关键字参数都会
        被传递给 *cls* 的构造器。如果传入 "None" （默认值），则会使用
        "JSONDecoder" 。

      * **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* 形参。

   * *parse_constant* 不再调用 'null' ， 'true' ， 'false' 。

   在 3.6 版本发生变更:

   * 所有可选形参现在都是 仅限关键字参数。

   * *fp* 现在可以是 *binary file* 。输入编码应当是 UTF-8 ， UTF-16 或
     者 UTF-32 。

   在 3.11 版本发生变更: 现在 "int()" 默认的 *parse_int* 会通过解释器
   的 整数字符串长度上限 来限制整数字符串的最大长度以帮助避免拒绝服务
   攻击。

   在 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)    | int                 |
   +-----------------+---------------------+
   | number (real)   | float               |
   +-----------------+---------------------+
   | true            | True                |
   +-----------------+---------------------+
   | false           | False               |
   +-----------------+---------------------+
   | null            | None                |
   +-----------------+---------------------+

   它还将 "NaN"、"Infinity" 和 "-Infinity" 理解为它们对应的 "float" 值
   ，这超出了 JSON 规范。

   *object_hook* 是一个可选的函数，它被调用时将传入每个要解码的 JSON
   对象而其返回值将被用来替代给定的 "dict"。 它可被用于提供自定义的反
   序列化操作 (比如支持 JSON-RPC 类提示)。

   *object_pairs_hook* 是一个可选的函数，它被调用时将传入每个以一个对
   照值的有序列表进行解码的 JSON 对象的结果。 *object_pairs_hook* 的返
   回值将被用于代替原本的 "dict"。 此特性可被用于实现自定义的解码器。
   如果还定义了 *object_hook*，则 *object_pairs_hook* 的优先级更高。

   在 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" ），那么控制字符将被允许在字
   符串内。在此上下文中的控制字符编码在范围 0--31 内的字符，包括
   "'\t'" (制表符）， "'\n'" ， "'\r'" 和 "'\0'" 。

   如果反序列化的数据不是有效 JSON 文档，引发 "JSONDecodeError" 错误。

   在 3.6 版本发生变更: 所有形参现在都是 仅限关键字参数。

   decode(s)

      返回 *s* 的 Python 表示形式（包含一个 JSON 文档的 "str" 实例）。

      如果给定的 JSON 文档无效则将引发 "JSONDecodeError"。

   raw_decode(s)

      从 *s* 中解码出 JSON 文档（以 JSON 文档开头的一个 "str" 对象）并
      返回一个 Python 表示形式为 2 元组以及指明该文档在 *s* 中结束位置
      的序号。

      这可以用于从一个字符串解码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, int 和 float 派生的枚举      | number          |
   +------------------------------------------+-----------------+
   | True                                     | true            |
   +------------------------------------------+-----------------+
   | False                                    | false           |
   +------------------------------------------+-----------------+
   | None                                     | null            |
   +------------------------------------------+-----------------+

   在 3.4 版本发生变更: 添加了对 int 和 float 派生的枚举类的支持

   要将其扩展至识别其他对象，需要子类化并实现 "default()"，如果可能还
   要实现另一个返回 "o" 的可序列化对象的方法，否则它应当调用超类实现 (
   来引发 "TypeError")。

   如果 *skipkeys* 为假值（默认），则当尝试对不为 "str", "int",
   "float", "bool" 或 "None" 的键进行编码时将会引发 "TypeError"。 如果
   *skipkeys* 为真值，这样的条目将被直接跳过。

   如果 *ensure_ascii* 为真值（默认值），输出将确保对所有输入的非
   ASCII 和不可打印字符进行转义。 如果 *ensure_ascii* 为假值，则所有字
   符将被原样输出，只有必须被转义的字符除外：引号、反斜线，以及 U+0000
   至 U+001F 范围的控制字符。

   如果 *check_circular* 为真值（默认），那么列表、字典和自定义的已编
   码对象将在编码期间进行循环引用检查以防止无限递归 (无限递归会导致
   "RecursionError")。 在其他情况下，将不会进行这种检查。

   如果 *allow_nan* 为真值（默认），那么 "NaN"、"Infinity" 和
   "-Infinity" 将照常进行编码。此行为不符合 JSON 规范，但与大多数基于
   JavaScript 的编码器和解码器一致。否则，编码这些浮点数将引发
   "ValueError"。

   如果 *sort_keys* 为真值 (默认为 "False")，那么字典的输出将按照键排
   序；这对回归测试很有用，以确保可以在日常基础上对 JSON 序列化结果进
   行比较。

   如果 *indent* 是一个非负整数或者字符串，那么 JSON 数组元素和对象成
   员会被美化输出为该值指定的缩进等级。 如果缩进等级为零、负数或者
   """"，则只会添加换行符。 "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" ）。

      例如，要支持任意的迭代器，你可以这样实现 "default()":

         def default(self, o):
            try:
                iterable = iter(o)
            except TypeError:
                pass
            else:
                return list(iterable)
            # 让基类的 default 方法引发 TypeError
            return super().default(o)

   encode(o)

      返回 Python *o* 数据结构的 JSON 字符串表达方式。例如:

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

   iterencode(o)

      编码给定对象 *o*，并产出每个可用的字符串表达方式。例如:

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


异常
====

exception json.JSONDecodeError(msg, doc, pos)

   拥有以下附加属性的 "ValueError" 的子类：

   msg

      未格式化的错误消息。

   doc

      正在解析的 JSON 文档。

   pos

      The start index of *doc* where parsing failed.

   lineno

      The line corresponding to *pos*.

   colno

      The column corresponding to *pos*.

   Added in version 3.5.


标准符合性和互操作性
====================

JSON 格式由 **RFC 7159** 和 ECMA-404 进行规范说明。 这一节详细介绍了本
模块与 RFC 的相符程度级别。 简单起见，"JSONEncoder" 和 "JSONDecoder"
子类，以及明确提到的形参以外的形参，都未被纳入考量。

此模块并不严格遵循 RFC，它实现了一些在 JavaScript 中有效但在 JSON 中无
效的扩展。尤其是：

* 无限和 NaN 数值是被接受并输出；

* 对象内的重复名称是接受的，并且仅使用最后一对属性-值对的值。

由于 RFC 允许符合 RFC 的解析器接收不符合 RFC 的输入文本，从技术上讲这
个模块的反序列化器在默认设置下符合 RFC。


字符编码
--------

RFC 要求使用 UTF-8 ， UTF-16 ，或 UTF-32 之一来表示 JSON ，为了最大互
通性推荐使用 UTF-8 。

正如 RFC 所允许（但不要求）的那样，此模块的序列化器默认设置
*ensure_ascii=True*，从而对输出进行转义，使结果字符串只包含可打印的
ASCII 字符。

除了 *ensure_ascii* 参数以外，此模块严格按照 Python 对象和 "Unicode 字
符串" 之间的转换来定义，因此不会直接处理字符编码的问题。

RFC 禁止在 JSON 文本的开头添加字节顺序标记（BOM），此模块的序列化器不
会在其输出中添加 BOM。RFC 允许但不要求 JSON 反序列化器忽略其输入中的初
始 BOM。此模块的反序列化器在遇到初始 BOM 时会引发 "ValueError"。

RFC 并未明确禁止包含不对应有效 Unicode 字符的字节序列的 JSON 字符串（
比如不成对的 UTF-16 代理项），但它确实指出这可能会导致互操作性问题。默
认情况下，此模块接受并输出此类序列的代码点（当它们存在于原始 "str" 中
时）。


Infinite 和 NaN 数值
--------------------

RFC 不允许表示无穷大或 NaN 数值。尽管如此，默认情况下，此模块接受并输
出 "Infinity"、"-Infinity" 和 "NaN"，如同它们是有效的 JSON 数字字面值:

   >>> # 这些调用均不会引发异常，但结果都不是合法的 JSON
   >>> json.dumps(float('-inf'))
   '-Infinity'
   >>> json.dumps(float('nan'))
   'NaN'
   >>> # 当反序列化时也一样
   >>> json.loads('-Infinity')
   -inf
   >>> json.loads('NaN')
   nan

序列化器中， *allow_nan* 参数可用于替代这个行为。反序列化器中，
*parse_constant* 参数，可用于替代这个行为。


对象中的重复名称
----------------

RFC 规定 JSON 对象内的名称应当是唯一的，但没有规定如何处理 JSON 对象中
的重复名称。默认情况下，此模块不会引发异常；而是对于给定名称忽略除最后
一个名称-值对之外的所有对:

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

The *object_pairs_hook* parameter can be used to alter this behavior.


顶级非对象，非数组值
--------------------

过时的 **RFC 4627** 指定的旧版本 JSON 要求 JSON 文本顶级值必须是 JSON
对象或数组（ Python "dict" 或 "list" ），并且不能是 JSON null 值，布尔
值，数值或者字符串值。 **RFC 7159** 移除这个限制，此模块没有并且从未在
序列化器和反序列化器中实现这个限制。

无论如何，为了最大化地获取互操作性，你可能希望自己遵守该原则。


实现限制
--------

一些 JSON 反序列化器的实现可能会在以下方面设定限制：

* 可接受的 JSON 文本大小

* JSON 对象和数组的最大嵌套层级

* JSON 数字的范围和精度

* JSON 字符串的内容和最大长度

此模块不强制执行任何上述限制，除了相关的 Python 数据类型本身或者
Python 解释器本身的限制以外。

当序列化为 JSON 时，注意可能消费你的 JSON 的应用中的此类限制。 特别是
，JSON 数字通常会被反序列化为 IEEE 754 双精度数字，从而受到该表示方式
的范围和精度限制。 当序列化极大的 Python "int" 值或者序列化 "exotic"
数值类型的实例 (如 "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

   将字典输出按照键的字母顺序排序。

   Added in version 3.5.

--no-ensure-ascii

   禁用非 ASCII 字符的转义，详情参见 "json.dumps()"。

   Added in version 3.9.

--json-lines

   将每个输入行解析为单独的 JSON 对象。

   Added in version 3.8.

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

   用于空白符控制的互斥选项。

   Added in version 3.9.

-h, --help

   显示帮助消息。

-[ 备注 ]-

[1] 正如 RFC 7159 的勘误表 所说明的，JSON 允许以字符串表示字面值字符
    U+2028 (LINE SEPARATOR) 和 U+2029 (PARAGRAPH SEPARATOR)，而
    JavaScript (在 ECMAScript 5.1 版中) 不允许。
