You are here:  Home » Python » – JSON编码器和解码器 – 互联网数据处理(Python教程)(参考资料)

json– JSON编码器解码器

源代码: Lib / json / __ init__.py


JSON(JavaScript Object Notation),由 RFC 7159指定(废弃 RFC 4627 )和byECMA-404,是一种灵感来自JavaScript对象文字语法的轻量级数据交换格式(虽然它不是JavaScript的严格子集[1])。

json公开了标准库用户熟悉的API marshalpickle modules.

编写基本的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({"4": 5, "6": 7}, sort_keys=True, indent=4)){    "4": 5,    "6": 7}

解码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 json.JSONEncoder.default(self, 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", "]"]

使用json.tool从shell验证和漂亮打印:

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

请参阅命令行界面了解详细文档.

注意

JSON是YAML 1.2的子集。由此模块的默认设置(特别是默认值separators值)生成的JSON也是YAML 1.0和1.1的子集。这个模块因此也可以用作YAML序列化器.

基本用法

json.dumpobj, fp, *, 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格式化的流到fp.write() – 支持类文件对象)使用这个转换表.

如果skipkeys为真(默认值:False),那么dict键不是基本类型(str, int, float, bool,None)将跳过而不是提出TypeError.

json模块总是产生str对象,而不是bytes对象。因此,fp.write()必须支持str输入

如果ensure_ascii为真(默认值),输出保证所有传入的非ASCII字符都被转义。如果ensure_ascii为false,这些字符将输出as-is.

如果check_circular为false(默认值:True),则对容器进行循环引用检查类型将被跳过,循环引用将导致OverflowError(或更糟).

如果allow_nan为假(默认:True),那么它将ValueError严格按照JSON规范序列化超出范围float values(nan,inf, -inf)。如果allow_nan为真,则其JavaScript等效(NaN,Infinity, -Infinity)将被使用

如果indent是一个非负整数或字符串,然后JSON数组元素和对象成员将使用该缩进级别进行漂亮打印。缩进级别0,负数或""仅插入换行符。None(默认值)选择最紧凑的表示。使用正整数缩进,每个级别有很多空格。如果indent是一个字符串(例如"\t"),该字符串用于缩进每个级别.

更改版本3.2:除了整数之外还允许indent的字符串.

如果指定的话,separators应该是(item_separator, key_separator)元组。默认是(", ", ": ")如果indentNone(",", ": ")除此以外。要获得最紧凑的JSON表示,您应该指定(",", ":")消除空白.

版本3.4更改:使用 (",", ": ")如果indent不是None.

如果指定,default应该是一个被调用的对象,否则无法序列化。它应该返回一个JSON可编码的对象版本或者TypeError。如果没有指定,则TypeError被引发

如果sort_keys为真(默认:False),那么输出的数据将按键排序.

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

更改版本3.6:所有可选参数现在仅限关键字.

注意

picklemarshal不同,JSON不是一个框架协议,因此尝试使用相同的dump()重复调用fp来序列化多个对象将导致一个无效的JSON文件.

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然后再转换为字典,则字典可能与原始字典不同。也就是说,loads(dumps(x)) != x如果x有nonstringkeys.

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

Deserialize fp(a .read()支持文本文件包含JSON文档的二进制文件使用这个转换表到Python对象.

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

object_pairs_hook是一个可选函数,将使用有序对列表解码的任何对象文字的结果调用。将使用object_pairs_hook的值来代替dict。此功能可用于实现自定义解码器。如果object_hook也定义,object_pairs_hook优先级.

更改版本3.1:添加对object_pairs_hook.

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

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

parse_constant,如果指定,将使用以下一个字符串调用:"-Infinity", "Infinity", "NaN"。如果遇到无效的JSON号码,这可用于引发异常.

改变版本3.1:parse_constant不再调用’null’,’true’,’false’。

使用自定义的JSONDecoder子类,用cls kwarg指定它;除此以外 JSONDecoder用来。其他关键字参数将被传递给类的构造函数.

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

在版本3.6中更改:所有可选参数现在都是仅限关键字.

在版本3.6中更改:fp现在可以是二进制文件。输入编码应为UTF-8,UTF-16或UTF-32.

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

Deserialize s(a str, bytesbytearray包含JSON文档的实例)使用这个转换表.

其他参数与load()中的含义相同,除了encoding被忽略和弃用.

如果被反序列化的数据不是有效的JSON文档,// JSONDecodeError会被举起来

版本3.6更改:s现在可以是bytes要么 bytearray。输入编码应为UTF-8,UTF-16或UTF-32 .

编码器和解码器

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

简单的JSON解码器

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

JSON Python
object dict
array list
string str
number(int) int
number(real)
真正
null 没有

它也理解NaN, Infinity-Infinity作为对应的float值,这超出了JSON规范

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

object_pairs_hook,如果指定将使用有序的对列表对解析的everyJSON对象的结果进行调用。将使用object_pairs_hook的返回值代替dict。此功能可用于实现自定义解码器。如果object_hook是alsodefined,则object_pairs_hook优先.

在版本3.1中更改:添加对object_pairs_hook.

parse_float的支持,如果指定,将使用要解码的每个JSONfloat的字符串调用。默认情况下,这相当于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"(tab),"\n", "\r""\0".

如果要反序列化的数据不是有效的JSON文件,一个JSONDecodeError将被抬起.

在版本3.6中更改:现在所有参数都是仅关键字.

decodes

返回s的Python表示(str包含JSON文档的实例).

JSONDecodeError如果给定的话会被提出JSON文件无效.

raw_decode(s)

sstr从aJSON文档开始)并返回Python表示的2元组和s中文档结束的索引.

这可以用于从可能具有extraneous的字符串中解码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-derived Enums number
True true
False false
没有 null

在版本3.4中更改:添加了对int和float派生的Enum类的支持.

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

如果skipkeys是假的(默认),那就是TypeError尝试编码不是str, int,floatNone的密钥。如果skipkeys为真,那么这些项目就是简单的.

如果ensure_ascii为真(默认值),输出将保证所有传入的非ASCII字符都被转义。如果ensure_ascii是错误的,这些字符将输出as-is.

如果check_circular为true(默认值),则将检查列表,dicts和customencoded对象编码过程中的循环引用可以防止无限递归(这会导致OverflowError)。否则,不会发生这样的检查.

如果allow_nan为真(默认值),那么NaN, Infinity-Infinity将被编码。此行为不符合JSON规范,但与大多数JavaScript basedencoders和解码器一致。否则,ValueError会对这些浮点数进行编码

如果sort_keys为真(默认:False),那么字典的输出将按以下顺序排序键;这对于回归测试很有用,可以确保日常比较JSON序列化.

如果indent是一个非负整数或字符串,然后JSON数组元素和对象成员将使用该缩进级别进行漂亮打印。缩进级别0,负数或""仅插入换行符。None(默认值)选择最紧凑的表示。使用正整数缩进,每个级别有很多空格。如果indent是一个字符串(例如"\t"),该字符串用于缩进每个级别.

更改版本3.2:除了整数之外还允许indent的字符串.

如果指定的话,separators应该是(item_separator, key_separator)元组。默认是(", ", ": ")如果indentNone(",", ": ")除此以外。要获得最紧凑的JSON表示,您应该指定(",", ":")消除空白.

版本3.4更改:使用 (",", ": ")如果indent不是None.

如果指定,default应该是一个被调用的对象,否则无法序列化。它应该返回一个JSON可编码的对象版本或者TypeError。如果没有指定,则TypeError被提升.

更改版本3.6:所有参数现在都是 keyword-only .

defaulto

在子类中实现此方法,使其返回o的serializable对象,或调用基本实现(以提升TypeError).

例如,为了支持任意迭代器,你可以实现defaultlike:

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 json.JSONEncoder.default(self, o)
encodeo

返回一个Python数据结构的JSON字符串表示,o。例如:

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

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

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

异常

exception json.JSONDecodeErrormsg, doc, pos

ValueError的子类,具有以下附加属性:

msg

未格式化的错误消息.

doc

正在解析的JSON文档.

pos

的起始索引doc解析失败的地方.

lineno

对应pos.

colno

对应于的列pos.

版本3.5中的新功能.

标准兼容性和互操作性

JSON格式由 RFC 7159 通过ECMA-404。本节详细介绍了该模块与RFC的兼容程度。为简单起见,JSONEncoderJSONDecoder除了那些明确提到的参数之外,不考虑子类和参数.

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

  • 接受并输出无限和NaN数值;
  • 接受对象中的重复名称,并且仅使用lastname-value对的值.

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

字符编码

RFC要求使用UTF-8,UTF-16或UTF-32表示JSON,UTF-8是最大互操作性的推荐默认值.

在RFC允许的情况下,虽然不是必需的,但是这个模块的序列化器默认设置ensure_ascii=True,从而转义输出,使得结果字符串只包含ASCII字符.

除了ensure_ascii参数,这个模块严格定义了Python对象和Unicode strings之间的转换,因此不会直接添加字符编码的问题.

RFC禁止在JSON文本的开头添加字节顺序标记(BOM),并且此模块的序列化程序不会向其输出添加BOM。RFC允许但不要求JSON反序列化器忽略其输入中的initialBOM。这个模块的解串器引发了ValueError当初始BOM存在时

RFC没有明确禁止包含与有效Unicode字符不对应的字节序列的JSON字符串(例如,未配对的UTF-16surrogates),但它确实注意到它们可能会导致互操作性问题。默认情况下,此模块接受并输出(如果存在)在原来的str)这些序列的代码点.

无限和NaN数值

RFC不允许表示无限或NaN数值。尽管如此,默认情况下,此模块接受并输出Infinity,-InfinityNaN,就好像它们是有效的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对象应该是唯一的,但不要求如何处理JSON对象中的重复名称。默认情况下,此模块不会引发异常;相反,它会忽略除给定名称的最后一个名称 – 值对之外的所有名称:

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

object_pairs_hook参数可用于改变此行为.

Top-level非对象,非数组值

过时的 RFC 4627 指定的旧版JSON要求JSON文本的顶级值必须是JSON对象或数组(Python dictlist),并且不能是JSON null,boolean,number或string值。 RFC 7159 删除了这个限制,并且这个模块没有并且从未在其序列化器或其解串器中实现该限制.

无论如何,为了最大程度的互操作性,您可能希望自己坚持自己的限制.

实现限制

一些JSON反序列化器实现可以设置限制:

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

此模块不会强加任何此类限制那些relatedPython数据类型本身或Python解释器本身.

序列化为JSON时,请注意可能使用JSON的应用程序中的任何此类限制。特别是,JSON数字通常被重新序列化为IEEE 754双精度数,因此受到该表示的范围和精度限制。当序列化Python int极大值的数据时,或者序列化“奇异”数值类型的实例,如decimal.Decimal.

命令行界面

时,这尤其相关源代码: Lib / json / tool.py


json.tool模块提供了一个简单的命令行界面来验证和漂亮打印JSON对象.

如果是可选的infileoutfile参数未指定,sys.stdinsys.stdout将分别使用:

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

在版本3.5中更改:输出现在与输入的顺序相同。使用--sort-keys选项按键按字母顺序对字典输出进行排序。

命令行选项

infile

要验证或打印的JSON文件:

$ python -m json.tool 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.

-h, --help

显示帮助信息

Footnotes

[1] RFC 7159的勘误表中所述,JSON允许在字符串中使用文字U + 2028(LINE SEPARATOR)和U + 2029(PARAGRAPH SEPARATOR)字符,而JavaScript(从ECMAScript版本5.1开始)则不允许.

评论被关闭。