首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python基础知识之模块——JSON

JSON模块

全称为:JavaScript Object Notation(JavaScript对象表示法)

作用

将Python对象序列化为JSON数据格式的字符串,可保存在文件中。

将包含JSON数据格式的字符串反序列化为Python对象。

序列化

把对象在内存中的结构转换成便于存储或传输的二进制或文本格式,而且以后可以在同一个系统或不同的系统中重建对象的副本。

JSON与pickle之间的区别

JSON与pickle功能类似,都是用于序列化Python对象,不同之处在于JSON可用于多种语言,尤其是JavaScript,而pickle只能被Python识别;pickle可以序列化任何Python对象,但是JSON在默认情况下只支持一些内置类型(str,int,float,list,tuple,dict),而对于自定义的类对象则需要我们自己编写编码和解码的程序。

JSON和Python中的数据类型对比

只要符合表格中的数据类型默认就可以被JSON序列化,但是Python中的元组在反序列化时会变成列表,因为JSON中没有元组这种数据类型。

JSON模块的函数

将Python对象序列化为JSON格式字符串并保存到fp(具有write()方法的类文件对象)中。

参数详解(基本上翻译自官方文档,部分内容添加了我的附加说明)

如果skipkeys为True(默认:False),那么当字典的键不是基本类型(str,int,float,bool, None)时将被跳过,而不是报TypeError异常。

如果ensure_ascii为true(默认值:True),则保证输出中所有传入的非ascii字符都被转义。如果ensure_ascii为false,则这些字符将按原样输出。

附加说明:比如为True时,汉字会以unicode编码输出至类文件对象(或者保存在文件中)。举个例子,为了方便,我们用dumps()来说明这个问题

当ensure_ascii = True时

而当ensure_ascii = False时

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

如果allow_nan为false(默认:True),那么当序列化超出JSON规范的float值时(比如:nan, inf,-inf)会报ValueError异常。如果allow_nan为真则会输出他们在JavaScript中对应的类型(NaN, Infinity, -Infinity)

如果indent是非负整数或字符串,那么JSON数组元素和对象成员将使用该缩进级别进行“漂亮打印”。缩进级别为0、为负、或""时仅插入换行符。 None(默认值)选择最紧凑的形式。按照不同级别缩进正整数数量的空格。如果indent是一个字符串(例如"\t"),则该字符串用于缩进每个级别。

附加说明:比如一个字典,当你使用indent参数时,JSON会至少在每个元素以及大括号之间加上换行符,使结果看上去很规整,如果没有indent参数,则会紧凑地在一行输出字典。

在3.2版中更改:indent参数除了整数之外,还允许使用字符串。

如果指定,separators应该是一个(item_separator, key_separator)元组。默认值是(', ', ': ')。要获得最紧凑的JSON表示,您应指定(', ', ': ')消除空白。

在版本3.4中更改:如果indent不是None,则默认值为:(', ', ': ')

如果指定,则default应该是一个函数,当目标对象原本不能被序列化时会调用这个函数,它应该返回一个JSON可编码的对象版本或者引发一个TypeError。如果未指定,则引发TypeError异常。

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

当创建自定义JSONEncoder子类(例如:定义子类,覆盖default方法以序列化额外类型)时需要指定cls,否则JSON会使用JSONEncoder的默认方法。

附加说明:也就是说当你序列化一个自定义的类对象时,你可能要创建一个JSONEncoder子类来把该对象转化为JSON支持的类型(字典),这个时候你可以指定cls来让JSON执行你定义的子类。

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

和dump类似,但是返回包含结果的字符串。参数同上。

注意 JSON的键/值对中的键始终是str类型。当字典转换为JSON时,字典的所有键都被强制转换为字符串。因此,如果将字典转换为JSON然后再转换回字典,则字典可能与原始字典不同。也就是说,如果x具有非字符串类型的键,则loads(dumps(x)) != x

用于将fp反序列化为Python对象,fp是具有read()方法的包含JSON文档的文本文件或者二进制文件。

参数详解:(基本上翻译自官方文档,部分内容添加了我的附加说明)

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

附加说明:其实就是让object_hook指向你自定义的解码器函数名,它会自动把需要解码的对象(字典)当作参数去调用这个函数,返回值取代原来的对象。

object_pairs_hook是一个可选函数,它会被调用,参数为任何对象字面量的解码结果组成的有序的成对儿列表(注:元组列表)。将使用object_pairs_hook的返回值取代 dict。此功能可用于实现自定义解码器。如果还定义了object_hook,则object_pairs_hook优先。

附加说明:object_pairs_hook指向的函数被调用时参数为由键值对儿(如果原型为字典时)组成的元组列表,

在3.1版中更改:添加了对object_pairs_hook的支持。

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

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

parse_constant:如果指定,将使用下列字符串之一调用它'-Infinity','Infinity','NaN'。如果遇到无效的JSON数字,将引发异常。

版本3.1中更改:parse_constant不会再调用'null','true','false'。

当创建自定义JSONDecoder子类(例如:定义子类,覆盖default方法以序列化额外类型)时需要指定cls,否则JSON会使用JSONDecoder的默认方法。其他的关键字参数将传递给类的构造函数。

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

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

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

用于将s反序列化为Python对象,s是包含JSON文档的str、bytes或者bytearray对象。

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

JSON模块中的两个类

当需要自定义编码和解码器时可以基于这两个类创建子类

该类用于解码JSON数据。相关参数与load()函数中使用的参数相同。

如果strict为False(默认为True),那么字符串中就会允许控制字符。在此上下文中,控制字符是0 - 31范围内的字符代码,包括'\t' (tab)、'\n'、'\r'和'\0'。

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

该类实例具有以下两个方法:

返回s的Python表示形式(s为一个包含JSON文档的字符串)

从s(以JSON文档开头的字符串)解码JSON文档,并返回一个包含两个元素的元组(Python_obj,index),其中,Python_obj为s中JSON文档的Python表示形式,index为JSON文档在s中结束的位置。

这可以用于从一个字符串解码JSON文档,该字符串末尾可能有无关数据。

该类用于将Python对象编码为JSON格式,相关参数与dump()函数使用的参数相同。

该类实例具有如下方法:

在子类中实现此方法,使其返回o的可序列化对象,或调用基本实现(以引发 TypeError)。

附加说明:在自定义编码器时我们在创建JSONEncoder的子类时一般会覆盖JSONEncoder中的default方法,通过自定义default方法来把不能序列化的类对象转化为可序列化的对象。然后调用下面的encode方法来进行编码。

返回Python对象o的JSON字符串表示

创建迭代器,对给定对象o进行编码,并yield可用的每个字符串表示形式。

参考资料:Python官方文档https://docs.python.org/3/library/json.html?highlight=json#json-to-py-table

欢迎关注我的公众号,谢谢!

封面Photo byMarkus SpiskeonUnsplash

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181022G1YS5I00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券