json (Internet Data) – Python 中文开发手册

[
  •   Python 中文开发手册

    json (Internet Data) - Python 中文开发手册

    2.6版本中的新功能。

    JSON(JavaScript对象表示法)由RFC 7159(废弃RFC 4627)和ECMA-404指定,是一种轻量级的数据交换格式,受JavaScript对象字面值语法的启发(尽管它不是JavaScript的严格子集)[1]。

    json公开了标准库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(""fooar")
    ""fooar"
    >>> print json.dumps(u'u1234')
    "u1234"
    >>> print json.dumps('\')
    "\"
    >>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
    {"a": 0, "b": 0, "c": 0}
    >>> from StringIO 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({'4': 5, '6': 7}, sort_keys=True,
    ...                  indent=4, separators=(',', ': '))
    {
        "4": 5,
        "6": 7
    }

    解码JSON:

    >>> import json
    >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
    [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
    >>> json.loads('"\"foo\bar"')
    u'"foox08ar'
    >>> from StringIO import StringIO
    >>> io = StringIO('["streaming API"]')
    >>> json.load(io)
    [u'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 json.JSONEncoder.default(self, obj)
    ...
    >>> 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', ']']

    json.tool在shell中使用来验证和漂亮打印:

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

    注意

    JSON是YAML 1.2的一个子集。由该模块的默认设置(特别是默认分隔符值)生成的JSON 也是YAML 1.0和1.1的子集。因此该模块也可以用作YAML串行器。

    1.基本用法

    json.dump(obj, fp, 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作为JSON格式的流序列化为fp(.write()支持文件类对象)。

    如果skipkeys为真(默认:False),那么字典键是一个基本类型(不str,unicode,int,long,float,bool,None)将被跳过,而不是养TypeError。

    如果ensure_ascii为true(缺省值),则输出中的所有非ASCII字符都会使用uXXXX序列进行转义,结果是str仅包含ASCII字符的实例。如果ensure_ascii为false,则写入fp的某些块可能是unicode实例。这通常发生是因为输入包含unicode字符串或使用编码参数。除非fp.write()明确理解unicode(如在codecs.getwriter())这可能会导致错误。

    如果check_circular为false(默认值:)True,那么容器类型的循环引用检查将被跳过,并且循环引用将导致OverflowError(或更糟糕)。

    如果allow_nan是假的(默认:True),那么这将是一个ValueError序列化超出范围的float值(nan,inf,-inf在JSON规范的严格遵守)。如果allow_nan是真实的,其JavaScript当量(NaN,Infinity,-Infinity)将被使用。

    如果indent是一个非负整数,那么JSON数组元素和对象成员将与该缩进级别相匹配。缩进级别0或负数只会插入换行符。None(默认)选择最紧凑的表示形式。

    注意

    由于缺省项目分隔符是', ',输出可能包括指定缩进时的尾部空白。你可以separators=(',', ': ')用来避免这种情况。

    如果指定,分隔符应该是一个(item_separator, key_separator)元组。默认情况下,(', ', ': ')使用。要获得最紧凑的JSON表示,您应该指定(',', ':')消除空白。

    encoding是str实例的字符编码,默认为UTF-8。

    如果指定,则默认值应为针对不能以其他方式进行序列化的对象调用的函数。它应该返回一个JSON可编码版本的对象或引发一个TypeError。如果未指定,TypeError则引发。

    如果sort_keys为true(默认值:)False,则字典的输出将按键排序。

    要使用自定义JSONEncoder子类(例如覆盖该default()方法来序列化其他类型的子类),请使用cls kwarg 指定它; 否则JSONEncoder使用。

    注意

    不像pickle和marshal,JSON是不是成帧协议,试图序列反复调用更多的对象dump()和相同的FP将导致一个无效的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序列化为str使用此转换表格式化的JSON 。如果ensure_ascii为false,则结果可能包含非ASCII字符,并且返回值可能是一个unicode实例。

    这些论点的含义与之相同dump()。

    注意

    JSON的键/值对中的键始终是该类型的键str。当字典转换为JSON时,字典中的所有键都被强制转换为字符串。因此,如果字典被转换成JSON然后又回到字典中,字典可能不等于原来的字典。也就是说,loads(dumps(x)) != x如果x具有非字符串键。

    json.load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

    使用此转换表,将fp(包含JSON文档的.read()支持类文件对象)反序列化为 Python对象。

    如果fp的内容使用非UTF-8(例如latin-1)的基于ASCII的编码进行编码,则必须指定适当的编码名称。不是基于ASCII的编码(例如UCS-2)是不允许的,应该用包装codecs.getreader(encoding)(fp)或简单解码到一个unicode对象并传递给它loads()。

    object_hook是一个可选函数,它将被解码的任何对象字面值的结果调用(a dict)。object_hook的返回值将被用来代替dict。此功能可用于实现自定义解码器(例如JSON-RPC类提示)。

    object_pairs_hook是一个可选函数,它将被调用,并且任何对象文本的结果都使用有序列表对进行解码。将使用object_pairs_hook的返回值来代替dict。此功能可用于实现自定义解码器,这些解码器依赖于解码键和值对collections.OrderedDict()的顺序(例如,会记住插入顺序)。如果还定义了object_hook,则object_pairs_hook优先。

    在版本2.7中更改:增加了对object_pairs_hook的支持。

    如果指定了parse_float,将会调用每个JSON浮点数的字符串进行解码。默认情况下,这相当于float(num_str)。这可以用来为JSON浮点数使用另一种数据类型或解析器(例如decimal.Decimal)。

    如果指定了parse_int,将使用每个JSON int的字符串进行解码。默认情况下,这相当于int(num_str)。这可以用来为JSON整数使用另一种数据类型或解析器(例如float)。

    parse_constant:如果指定,将与下列字符串之一叫'-Infinity','Infinity','NaN'。如果遇到无效的JSON号码,这可以用来引发异常。

    在版本2.7中更改:parse_constant不再被'null','true','false'调用。

    要使用自定义JSONDecoder子类,请使用clskwarg 指定它; 否则JSONDecoder使用。其他关键字参数将传递给该类的构造函数。

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

    反序列化小号(一个str或unicode含JSON文档实例)使用该转换表Python对象。

    如果s是一个str实例,并且使用UTF-8以外的基于ASCII的编码(例如latin-1)进行编码,则必须指定适当的编码名称。不是基于ASCII的编码(如UCS-2)是不允许的,应该首先解码unicode。

    其他论点的含义与之相同load()。

    2.编码器和解码器

    class json.JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict[, object_pairs_hook]]]]]]])

    简单的JSON解码器。

    默认情况下,在解码中执行以下翻译:

    JSON

    Python

    目的

    字典

    排列

    名单

    统一

    数字(int)

    int,long

    数量(实际)

    浮动

    真正

    真正

    空值

    没有

    它也理解NaN,Infinity并且-Infinity作为它们相应的float值,它超出了JSON规范。

    编码决定用于解释str由此实例解码的任何对象的编码(默认为UTF-8)。解码unicode对象时不起作用。

    请注意,目前只有编码是ASCII工作的超集,其他编码的字符串应该以as的形式传入unicode。

    如果指定了object_hook,将会调用每个JSON对象的解码结果,并使用它的返回值代替给定的值dict。这可以用来提供自定义的反序列化(例如,支持JSON-RPC类提示)。

    如果指定object_pairs_hook,将调用每个JSON对象的结果,并使用有序的对列表进行解码。将使用object_pairs_hook的返回值来代替dict。此功能可用于实现自定义解码器,这些解码器依赖于解码键和值对collections.OrderedDict()的顺序(例如,会记住插入顺序)。如果还定义了object_hook,则object_pairs_hook优先。

    在版本2.7中更改:增加了对object_pairs_hook的支持。

    如果指定了parse_float,将会调用每个JSON浮点数的字符串进行解码。默认情况下,这相当于float(num_str)。这可以用来为JSON浮点数使用另一种数据类型或解析器(例如decimal.Decimal)。

    如果指定了parse_int,将使用每个JSON int的字符串进行解码。默认情况下,这相当于int(num_str)。这可以用来为JSON整数使用另一种数据类型或解析器(例如float)。

    parse_constant:如果指定,将与下列字符串之一叫'-Infinity','Infinity','NaN'。如果遇到无效的JSON号码,这可以用来引发异常。

    如果strict为假(True是默认值),那么控制字符将被允许在字符串内。此上下文中的控制字符是字符代码在0-31范围内的字符,包括' '(制表符)' ',' '和''。

    如果被反序列化的数据不是有效的JSON文档,ValueError则会引发。

    decode(s)

    返回s(包含JSON文档的实例str或Python unicode实例)的Python表示形式。

    raw_decode(s)

    从s(str或unicode从JSON文档开始)解码JSON文档,并在文档结束的s中返回Python表示形式的2元组和索引。

    这可以用来从一个字符串解码JSON文档,该字符串可能在最后有多余的数据。

    class json.JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default]]]]]]]]])

    用于Python数据结构的可扩展JSON编码器。

    默认支持以下对象和类型:

    Python

    JSON

    字典

    目的

    列表,元组

    排列

    str,unicode

    int,long,float

    真正

    真正

    没有

    空值

    为了扩展这个以识别其他对象,子类并default()使用另一个方法实现一个方法,o如果可能的话,该方法返回一个可序列化对象,否则它应该调用超类实现(提升TypeError)。

    如果skipkeys为false(缺省值),那么它将TypeError尝试编码不是str,int,long,float或None。如果skipkeys为true,则简单地跳过这些项目。

    如果ensure_ascii为true(缺省值),则输出中的所有非ASCII字符都会被uXXXX序列转义,并且结果是str仅由ASCII字符组成的实例。如果ensure_ascii为false,则结果可能是一个unicode实例。如果输入包含unicode字符串或使用编码参数,通常会发生这种情况。

    如果check_circular为true(默认值),那么在编码期间将检查列表,字典和自定义编码对象的循环引用,以防止无限递归(这会导致OverflowError)。否则,不会进行这种检查。

    如果allow_nan为真(默认值),然后NaN,Infinity和-Infinity将被编码为这样。这种行为不符合JSON规范,但与大多数基于JavaScript的编码器和解码器一致。否则,这将是一个ValueError编码这样的浮游物。

    如果sort_keys为true(默认值:)False,则字典的输出将按键排序; 这对于回归测试非常有用,可以确保JSON序列化可以在日常的基础上进行比较。

    如果indent是一个非负整数(None默认情况下),那么JSON数组元素和对象成员将会与该缩进级别相匹配。缩进级别0只会插入换行符。None是最紧凑的代表。

    注意

    由于缺省项目分隔符是', ',输出可能包括指定缩进时的尾部空白。你可以separators=(',', ': ')用来避免这种情况。

    如果指定,分隔符应该是一个(item_separator, key_separator)元组。默认情况下,(', ', ': ')使用。要获得最紧凑的JSON表示,您应该指定(',', ':')消除空白。

    如果指定,则默认值应为针对不能以其他方式进行序列化的对象调用的函数。它应该返回一个JSON可编码版本的对象或引发一个TypeError。如果未指定,TypeError则引发。

    如果编码不是None,那么所有输入字符串将在JSON编码之前使用该编码转换为unicode。默认值是UTF-8。

    default(o)

    在子类中实现此方法,以便返回o的可序列化对象,或调用基本实现(以提高a TypeError)。

    例如,要支持任意迭代器,可以像这样实现默认值:

    def default(self, o):
       try:
           iterable = iter(o)
       except TypeError:
           pass
       else:
           return list(iterable)
       # Let the base class default method raise the TypeError
       return JSONEncoder.default(self, o)

    encode(o)

    返回Python数据结构的JSON字符串表示形式o。例如:

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

    iterencode(o)

    对给定对象o进行编码,并将每个字符串表示视为可用。例如:

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

    3.标准兼容性和互操作性

    JSON格式由RFC 7159和ECMA-404指定。本节详细介绍了该模块对RFC的遵从级别。为了简单起见,JSONEncoder和JSONDecoder亚类和除了明确提及的那些其它参数,都没有考虑。

    该模块不严格遵守RFC,实现了一些有效的JavaScript但不是有效的JSON的扩展。尤其是:

    无限和NaN数值被接受和输出;对象中的重复名称将被接受,并且只使用最后一个名称 - 值对的值。

    由于RFC允许RFC兼容的解析器接受不符合RFC的输入文本,因此该模块的解串器在技术上符合RFC默认设置。

    3.1。字符编码

    RFC要求使用UTF-8,UTF-16或UTF-32来表示JSON,UTF-8是最大互操作性的推荐默认值。因此,该模块使用UTF-8作为其编码参数的默认值。

    该模块的解串器仅直接与ASCII兼容的编码一起工作; UTF-16,UTF-32和其他ASCII不兼容的编码需要使用文档中描述的解串器编码参数的解决方法。

    根据RFC的规定,尽管不是必需的,但该模块的序列化程序默认情况下会设置ensure_ascii = True,从而转义输出,以便生成的字符串仅包含ASCII字符。

    RFC禁止将字节顺序标记(BOM)添加到JSON文本的开头,并且此模块的串行器不会将BOM添加到其输出中。RFC允许但不要求JSON解串器忽略其输入中的初始BOM。ValueError当存在初始BOM时,该模块的解串器会产生一个。

    RFC没有明确禁止包含与有效的Unicode字符不对应的字节序列的JSON字符串(例如不成对的UTF-16替代品),但是它确实注意到它们可能导致互操作性问题。默认情况下,该模块接受并输出(当存在于原始中str)用于这种序列的代码点。

    3.2。无限和NaN数值

    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参数来改变这种行为。

    3.3。对象中的重复名称

    RFC指定JSON对象中的名称应该是唯一的,但不要求JSON对象中的重复名称应该如何处理。默认情况下,该模块不会引发异常; 相反,它忽略了给定名称以外的所有名称 - 值对:

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

    该object_pairs_hook参数可以用来改变这种行为。

    3.4。顶级非对象,非数组值

    由过时的RFC 4627指定的JSON的旧版本要求JSON文本的顶级值必须是JSON对象或数组(Python dict或list),并且不能是JSON null,布尔值,数字或字符串值。RFC 7159删除了这个限制,而且这个模块没有,也没有在其串行器或解串器中实现这个限制。

    无论如何,为了获得最大的互操作性,您可能希望自己自愿遵守限制。

    3.5。实施限制

    一些JSON解串器实现可能会对以下内容设置限制:

    接受的JSON文本的大小JSON对象和数组的最大嵌套级别JSON数字的范围和精度JSON字符串的内容和最大长度

    除了相关的Python数据类型本身或Python解释器本身以外,本模块不会强加任何限制。

    序列化为JSON时,请注意可能会使用JSON的应用程序中的任何此类限制。特别是,JSON数字被反序列化为IEEE 754双精度数字并且因此受制于该表示的范围和精度限制是很常见的。当序列化int极大数量的Python 值时,或者在序列化“奇异”数字类型的实例时,这尤其重要decimal.Decimal。

    1

    正如RFC 7159勘误中所述,JSON允许在字符串中使用文字U + 2028(LINE分隔符)和U + 2029(PARAGRAPH SEPARATOR)字符,而JavaScript(从ECMAScript版本5.1开始)则不允许。

  •   Python 中文开发手册
    ]
    转载请保留页面地址:https://www.breakyizhan.com/python/35045.html
    原文地址:https://www.cnblogs.com/breakyizhan/p/13239012.html