Java开发者的Python进修指南:JSON利器之官方json库、demjson和orjson的实用指南
JSON
JSON作为目前最流行的传输格式,在Python中也有相应的实现方式。由于JSON格式的文本可以跨平台并且简单易用,因此被广泛传播。因此,我们今天的主要讨论内容是如何熟练地应用Python的JSON库来处理将JSON映射到文本,以及如何从文本映射到对象中。现在,让我们开始探讨这个话题。
官方json库
在Python中,官方提供了多个JSON库,包括标准库中的json、marshal和pickle。其中,我个人比较喜欢使用json库,因为pickle存在一些反序列化漏洞,并且它处理的是二进制类型的数据。相比之下,json更类似于我们在Java中使用的fastjson,但它们之间仍然存在一些明显的差异。接下来,我们继续深入了解一下。
简单用法
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"]'
上面提到的是官方提供的一些JSON库的示例,我们不再深入讨论。现在,让我们来讲解一下在工作中如何使用JSON进行对象的序列化和反序列化。
进阶用法
当前端返回给后端一串JSON文本时,我们可以使用json.loads()方法将其正确映射到Python对象中。这个过程称为反序列化。使用对象来处理数据会更规范一些,尽管对于一些快速开发来说,直接使用字典可能更方便。不过,我可以给你演示一下如何使用对象进行反序列化。
首先,我们可以定义一个类来表示我们要映射的对象,然后利用json.loads()方法将JSON文本转换为字典。接着,我们可以使用字典的键值对来为对象的属性赋值。这样,我们就成功地将JSON文本映射到了对象中。让我来给你演示一下:
{"status":1,"info":"成功","data":{"id":"52","age":"70"}}
上面是我们接收的参数,我们需要对其进行处理,将其映射到相应的对象中。
import json
class Response_data:
def __init__(self, id, feed_id):
super().__init__()
self.id = id
self.feed_id = feed_id
class Response:
def __init__(self, status=None, info=None, data=None) -> None:
super().__init__()
self.status = status
self.info = info
self.data = data
def to_json(self):
return {
"status": self.status,
"info": self.info,
"data": self.data.__dict__ if self.data else None
}
@staticmethod
def object_hook(d):
if "status" in d :
return Response(d['status'], d['info'], d['data'])
else:
return Response_data(d['id'],d['feed_id'])
body = '{"status":1,"info":"发布成功","data":{"id":"52","feed_id":"70"}}'
resp = json.loads(body, object_hook=Response.object_hook)
print(json.dumps(resp.to_json(),ensure_ascii=False))
在上述代码中,我们使用了object_hook参数。object_hook参数的主要作用是用来自定义解码函数。它的入参是标准反序列化后的字典,我们可以根据自己的规则将其转换为所需的格式。
为什么我需要在object_hook中编写if判断呢?这是因为object_hook参数在反序列化时是递归的。由于我的JSON文本是嵌套的结构,所以每一层嵌套都会递归一次。因此,我需要先封装好Response_data,然后才能继续封装Response。这与Java中的JSON序列化有很大的不同。在Java中,我们不需要关注这么多细节。但是在Python中,我们不仅需要指定参数名称,还需要处理好嵌套结构。
如果你在解析中文时遇到问题,很可能是由于默认的编码格式不支持中文字符。为了解决这个问题,你可以尝试使用ensure_ascii=False参数。通过设置这个参数,可以禁用ASCII编码,从而保留中文字符的原始形式。
多说一句
json库是在Python2.6版中引入的,因此如果您使用的是更早版本的Python,您可以通过PyPI获取simplejson库来实现相同的功能。
json 类型转换到 python 的类型对照表:
| JSON | Python |
|---|---|
| object | dict |
| array | list |
| string | unicode |
| number (int) | int, long |
| number (real) | float |
| true | True |
| false | False |
| null | None |
三方json库
demjson
Demjson是一个Python的第三方模块库,它提供了编码和解码JSON数据的功能,并且还包含了JSONLint的格式化和校验功能。此外,Demjson还支持hook,可以通过decode函数配置和set_hook函数配置两种方式进行配置。
你可以在以下网址找到Demjson的Github地址:https://github.com/dmeranda/demjson。同时,你也可以在官方地址http://deron.meranda.us/python/demjson/上了解更多关于Demjson的信息。
decode函数是Demjson提供的一个功能强大的函数,它可以接受多个参数,其中包括hook函数。通过键值对的方式指定hook函数,键是hook函数的名称,而值是hook函数本身。
如果你在安装Demjson时遇到了报错,可能是因为需要降低setuptools的版本到57.5.0。不过我就不进行实验和验证了。
orjson
在日常的开发工作中,我们经常需要将一些数据存储为JSON格式。而最常用的方法是使用Python原生的JSON库。然而,我们发现该库的速度较慢,特别是当数据量过大时,使用起来非常不便。幸运的是,我们发现了orjson这个强大的工具,它不仅支持多种类型的数据序列化,还可以根据开发者的需求进行定制化输出。与其他第三方JSON库相比,orjson具有更高的效率,因此在处理大量数据时,它是一个更好的选择。
我们来看一下它是如何运作的。下面是一个使用dataclasses模块的示例代码:
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
# 假设您有一个包含 JSON 数据的字符串
json_data = '{"name": "xiaoyu", "age": 18}'
# 使用 orjson 反序列化 JSON 数据
import orjson
data_dict = orjson.loads(json_data)
# 将字典转换为 Person 对象
person = Person(**data_dict)
# 现在,您可以像访问对象属性一样访问 person 对象的属性
print(person.name) # 输出 "xiaoyu"
print(person.age) # 输出 18
经过仔细观察,我发现这两种方式看起来确实非常相似,官方的JSON模块也能实现相同的功能。但是当我们尝试将person对象转换成字符串时,官方的JSON模块无法完成这个任务,而orjson则可以轻松胜任。
orjson.dumps(person)
option参数
orjson还支持使用option参数来定制序列化的结果。当然,还有很多其他的选项可以使用,但是由于太多了,我就不一一列举了。不过,我可以简单举一个日期格式的例子,因为在我们的工作中,通常需要对日期格式进行处理。
option=orjson.OPT_OMIT_MICROSECONDS: 序列化的日期时间对象将以字符串形式呈现,而不是默认的 ISO 8601 格式。这个选项在某些情况下可能更加便利,尤其是在与其他系统进行数据交换时。通过使用该选项,您可以确保日期时间对象的格式与其他系统的要求相匹配,从而简化数据交换的过程。
import orjson
from datetime import datetime
data = {"name": "xiaoyu", "dob": datetime(2020, 5, 1)}
json_data = orjson.dumps(data, option=orjson.OPT_OMIT_MICROSECONDS)
print(json_data.decode())
为什么需要进行解码呢?原因主要在于orjson返回的是二进制数据,而我们需要将其转换为字符串类型,因此需要进行解码操作。
总结
JSON是一种流行的数据传输格式,Python中有多种处理JSON的方式。官方的json库是最常用的,它提供了简单的用法来序列化和反序列化JSON文本。此外,它还支持自定义解码函数,可以将JSON映射到对象中。
在使用官方json库时,可以使用dumps函数将Python对象转换为JSON文本,也可以使用loads函数将JSON文本转换为Python对象。如果需要自定义解码函数,可以使用object_hook参数来实现。
除了官方的json库,还有一些第三方的库可供选择。例如,demjson库提供了JSON数据的编码和解码功能,并支持hook函数。另外,orjson库是一个高效的JSON库,支持多种数据类型的序列化,并提供了定制化输出的选项。
总之,掌握Python的JSON处理库对于处理JSON数据非常重要,可以帮助我们在项目开发中更加高效地处理JSON数据。
Java开发者的Python进修指南:JSON利器之官方json库、demjson和orjson的实用指南的更多相关文章
- python学习之路-day4-装饰器&json&pickle
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 一.生成器 1.列表生成式 >>> L = [x * x for x in range(10 ...
- JSON取代XML?--JSON入门指南
定义 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C# ...
- 《Android Studio实用指南》7.1 AndroidStudio代码检查工具概述
本文节选自<Android Studio实用指南> 作者: 毕小朋 目前本书已上传到百度阅读, 在百度中搜索[Anroid Studio实用指南]便可以找到本书. Android Stud ...
- 推荐几个IDEA插件,Java开发者撸码利器(转载)
推荐几个IDEA插件,Java开发者撸码利器. 这里只是推荐一下好用的插件,具体的使用方法不一一详细介绍. JRebel for IntelliJ 一款热部署插件,只要不是修改了项目的配置文件,用 ...
- 阿里巴巴泰山版《Java 开发者手册》,也是一份防坑指南
我是风筝,公众号「古时的风筝」,一个不只有技术的技术公众号,一个在程序圈混迹多年,主业 Java,另外 Python.React 也玩儿的 6 的斜杠开发者. Spring Cloud 系列文章已经完 ...
- 100个高质量Java开发者博客
ImportNew注:原文中还没有100个.作者希望大家一起来推荐高质量的Java开发博客,然后不段补充到这个列表.欢迎你也参与推荐优质的Java开发博客.(声明一下:我们的数学不是体育老师教的!:) ...
- 转:100个高质量Java开发者博客
原文来自于:http://www.importnew.com/7469.html ImportNew注:原文中还没有100个.作者希望大家一起来推荐高质量的Java开发博客,然后不段补充到这个列表.欢 ...
- 【伯乐在线】100个高质量Java开发者博客
本文由 ImportNew - 夏千林 翻译自 programcreek.欢迎加入翻译小组.转载请见文末要求. ImportNew注:原文中还没有100个.作者希望大家一起来推荐高质量的Java开发博 ...
- python模块之pickle、shelve、json
一 什么是序列化 序列化指的是将内存中的数据结构转化为一种中间格式,并存储到硬盘上. (反序列化:将硬盘上存储的中间格式数据再还原为内存中的数据结构) 二 为什么要序列化 持久保持状态 需知一个软件/ ...
- JAVA开发者大会:拍拍贷MQ系统原理与应用
--喜欢记得关注我哟[shoshana]-- 前记: 5月12号参加了JAVA开发者大会,就<拍拍贷消息系统原理及应用> 作者:李乘胜老师 关于PMQ的分享整理一下笔记以及笔记的思考 和复 ...
随机推荐
- MySQL 数据目录
MySQL 的数据目录 1. MySQL 的主要目录结构 方式1:通过命令搜索 find / -name mysql 方式2(推荐):通过查看配置文件获取目录结构 vim /etc/my.cnf (重 ...
- shell中 << EOF 和 EOF 使用
转载请注明出处: EOF(End of File)在Shell中通常用于指示输入的结束,并在脚本或命令中进行多行输入.它允许用户指定一个特定的分界符来表示输入的结束,通常用于创建临时文件.重定向输入或 ...
- ifconfig详解
linux下ifconfig命令详解 ifconfig 是一个用来查看.配置.启用或禁用网络接口的工具,这个工具极为常用的.可以用这个工具来临时性的配置网卡的IP地址.掩码.广播地址.网关等.也可以把 ...
- CodeForces 1459C 数论 GCD
CodeForces 1459C 数论 GCD 原题链接 题意 首先给出n个数 之后给出m个数,每次问之前的n个数加上当前的这个数之后,总体的gcd是多少,也就是答案需要求出m个总体的gcd 思路 因 ...
- 7、Flutter GridView网格布局组件(遍历)
GridView创建网格列表主要有下面三种方式 1.可以通过GridView.count 实现网格布局 一行的 Widget 数量 class HomePage extends Stateles ...
- ServiceWorker工作机制与生命周期:资源缓存与协作通信处理
在 <web messaging与Woker分类:漫谈postMessage跨线程跨页面通信>介绍过ServiceWorker,这里摘抄跟多的内容,补全 Service Worker 理解 ...
- 在线就能用的 SQL 练习平台(附SQL学习文档)
对大数据和数据分析感兴趣的同学,如何入门一直是一个大问题. 而对于找工作的同学,笔试和面试环节也一直是一个让人头疼的问题. 其实企业也很头疼,不进行笔试,怕被面试者忽悠.进行笔试可能又把某些大牛筛出去 ...
- Log4Shell 漏洞披露已近一年,它对我们还有影响吗?
在 Log4Shell 高危漏洞事件披露几乎整整一年之后,新的数据显示,对全球大多数组织来说,补救工作是一个漫长.缓慢.痛苦的过程. 根据漏洞扫描领先者 Tenable 公司的遥测数据来看,截至今年1 ...
- 对话 BitSail Contributor | 梁奋杰:保持耐心,享受创造
2022 年 10 月,字节跳动 BitSail 数据引擎正式开源.同期,社区推出 Contributor 激励计划第一期,目前已有 13 位外部开发者为 BitSail 社区做出贡献,成为了首批 B ...
- Solon2 开发之IoC,七、切面与函数环绕拦截
想要环绕拦截一个 Bean 的函数.需要三个前置条件: 通过注解做为"切点",进行拦截(不能无缘无故给拦了吧?费性能) Bean 的 method 是被代理的 在 Bean 被扫描 ...