python Json的一点收获,自定义序列化方法

本文介绍了Python中JSON模块的基本使用方法,包括简单数据类型的编码和解码、人性化使用、编码字典、处理自定义类型、编码和解码类、流和文件的处理以及混合数据流的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

PyMOTW: json

  • 模块: json
  • 目的: JavaScript对象格式序列器
  • python版本: 2.6

json模块提供了一个类似于pickle中用于转换内存中python对象为一个序列表示形式(“JavaScript Object Notation”)的API接口. 但和pickle不同的是, JSON在其他很多语言中都有对应实现(特别是在JavaScript中), 使其更适用于内部应用间的通信. 在一个AJAX应用中, JSON可能对于web服务器和客户端间的通信, 使用最为广泛, 但它也不仅限于这类应用.

 

 

 

简单数据类型的编码和解码

编码器默认支持Python的本地类型(如int, float, list, tuple, dict).

 

 

 

编码器处理之后的值和Python的repr()的输出值很类似.

 

编码之后的解码所获的的值可能和原先的对象不是完全一致.

 

比如说, 元组会被转换为JSON的列表.

 

 

人性化使用 vs 紧凑型输出

JSON优于pickle的另外一点是其结果具有可读性. dumps()函数接收多个参数用于更好的输出结构. 比如说. sort_keys参数告诉编码器按照顺序输出字典的键值, 而不是随机无序的.

 

排序之后更容易让人看出结果, 也使进行JSON的比较输出成为可能.

 

 

对于高度嵌套的数据结构, 你会想在输出结果中增加缩进以更好的显示其格式.

 

当indent参数是一非负整数时, 输出的结构和pprint更为接近, 在每个缩进层次上都有前导空格.

 

像这种类型输出的数据在传输过程中需占用更多的字节, 不过, 在实际生产环境中没有必要使用缩进格式. 实际上, 你可以设置数据的分隔符来让结果更为紧凑.

 

dumps()函数的separators参数是一个元组, 包含分隔列表各项和字典键值各项的字符串. 默认是(‘, ‘, ‘: ‘). 可以去掉后者中的空格, 我们可以得到较紧凑的输出.

 

 

编码字典

JSON格式中, 字典的键被限制为字符串类型. 如果字典中的键是其他类型, 那么在编码这个对象时会产生一个TypeError异常. 一种解决这个限制的方法是, 在编码时, 使用skipkeys参数跳过所有非字符串类型的键.

 

非字符串类型的键被忽略, 而不抛出一个异常.

 

 

自定义类型的处理

上面所有的例子都是用了Python的内置类型作为例子, 因为他们都被json本身支持. 当然, 自定义类型也常常需要正确编码. 这里有两种情况:

第一, 对于一个类的编码:

 

编码一个MyObj对象的最简单方式是定义个转换函数, 用于将位置类型转换出呢个已知类型. 你没有必要自己进行编码, 而仅需要将一个对象转换成另一个对象.

 

在convert_to_builtin_type()函数中, 不被json识别的类对象被转换成一个包含足够能重建这个对象的字典信息.

 

 

为了能解码结果数据并创建一个MyObj实例, 我们需要配合解码器以便可以从模块中导入类并创建实例. 我们在loads()函数中使用object_hook参数.

在输入数据流中, 对于解码获得的每个字典都会调用object_hook, 将这个字典转换成其他类型的对象. hook函数返回的是调用程序所需要的对象, 而不是字典.

 

由于json将字符串值转换成unicode对象, 所以我们需要将作为类构造器的参数重新编码为ASCII字符串.

 

 

对于内置类型也都有类似的hooks, 如整型(parse_int), 浮点型(parse_float), 常量(parse_constant).

编码和解码类

除了上述的这些函数外, json模块还提供了编码和解码类. 直接使用这些类, 你可以访问到额外的API接口或者定制创建它的子类.

JSONEncoder提供了一个产生编码数据”块”的的迭代接口, 这在写入一个文件或网络sockets时(不需要在内存中完整表示整个数据)是非常方便的,

 

正如你看到的, 数据是以逻辑单位形式输出的, 而不是按照数据长度输出.

 

 

encode()方法基本上等价于’‘.join(encoder.iterencode()), 只是多了些附加错误检查.

为了能够编码任何类型的对象, 我们可以编写一类似于上述的convert_to_builtin_type()函数去重载default()方法.

 

这里输出的结果是和先前的实现一致的.

 

解码后将字典转换成一个对象, 在先前实现的基础上稍作修改即可.

 

输出结果也是和先前例子中输出的一样.

 

 

流和文件的处理

到目前为止的所有例子, 我们都假设待编码的数据都是一次性完整加载到内存中的. 但对于大型数据结构来说, 将编码数据直接写入一个类文件对象, 可能会更好. load()和dump()函数可以接收一个用于读或写的类文件对象的引用.

 

对于socket来说, 也和正常文件句柄类似.

 

虽然一次性读取部分数据不是很好, 但是load()函数仍然提供了从流数据输入中封装生成对象的功能.

 

 

 

混合数据流

JSONDecoder包含了raw_decode()方法, 用于解码在很多数据组成的数据结构, 例如包含多余文本的JSON数据. 返回的值是从输入数据中解码获得的对象, 数据中的index表示解码对象结束时所在的位置.

 

不幸的是, 这仅仅在对象出现在输入流的开始处才有效.

 

 

原文地址:http://vbarter.cn/pymotw/documents/json.html

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值