Java开发者的Python进修指南:JSON利器之官方json库、demjson和orjson的实用指南

JSON

json作为现在最流行的传输格式,在Python中也有响应的实现方式,就是因为JSON格式的文本可以跨平台并且简单易用,所以广为流传,那么我们今天就主要探讨一下,如何熟练的应用Python的JSON库来处理json映射到文本,并且再从文本映射到对象中。我们现在就开始。

官方json库

官方的json库有很多,标准库:json 、 marshal、 pickle ,其中我最喜欢用其中的json,因为pickle 存在很多反序列化漏洞,并且是二进制类型的,json更像我们Java中的fastjson一样操作,但是还是跟fastjson有很大差别的。我们继续看。

简单用法

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"]'

上面这都是官方实例,我们不多说了,我们讲解一下我们工作中如何使用json进行序列化和反序列化对象。

进阶用法

假如我们的前端返回给后端一串json文本,我们如何正确的映射到对象中呢?其实对于我来讲,使用对象反而会影响Python的快速开发,直接字典用起来就完事了,别面向对象了了。但是确实对象更规范一些,我来演示一下:

{"status":1,"info":"成功","data":{"id":"52","age":"70"}}

上面是我们接收的参数,我们处理一下将其映射到对象中。

python 复制代码
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参数,这个参数主要就是用来自定义解码函数的。入参数标准反序列化后的dict,我们可以根据自己的规则转换输出为想要的格式。

我为什么需要在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函数配置。

Github 地址:github.com/dmeranda/de...

官方地址:deron.meranda.us/python/demj...

decode函数可以指定很多参数,其中就包括hook函数。hook函数的指定是使用键值对的方式,键是hook函数的名称,值是hook函数。

由于安装报错,需要降低setuptools到57.5.0版本,所以我就不去实验了。

orjson

在日常的开发工作中,我们经常需要将一些数据存储为JSON格式,最常用的就是Python原生的JSON库,但是该库速度较慢, 当数据量过大时,使用不便。而orjson的功能强大,它支持多种类型的数据序列化,开发者还可以根据需要定制化输出, 与其他第三方JSON库相比,效率更高。

我们来看下他是如何运作的。下面是一个使用 dataclasses 模块的示例:

python 复制代码
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没啥区别,官方json也能做到,但是我们再将person对象dumps出来时,json是不支持的,orjson是可以支持的。

python 复制代码
orjson.dumps(person)

option参数

orjson还支持使用option参数可以定制序列化的结果。太多的我就不列举了,我就简单举一个日期格式的例子吧,毕竟日期格式基本上我们工作中都需要做一下处理。

option=orjson.OPT_NAIVE_UTC: 这个选项会使得序列化的日期时间对象以字符串的形式呈现,而不是默认的 ISO 8601 格式。这在一些情况下可能更方便,例如与其他系统进行数据交换时。

python 复制代码
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())

为什么需要decode呢?主要是因为orjson返回的二进制,如果想要str类型所以需要解码。

总结

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数据。

相关推荐
Eric.Lee202118 分钟前
数据集-目标检测系列-自行车检测数据集 bike>> DataBall
人工智能·python·深度学习·目标检测·数据集·物体检测·自行车检测数据集
山语山21 分钟前
机器学习与深度学习
前端·人工智能·python·深度学习·机器学习·机器人
莱布尼茨25 分钟前
Java Web 拾遗
后端·组件
TuringSnowy39 分钟前
用矩阵和统计报告估计polynomial线性回归的系数python
笔记·python
huanxiangcoco39 分钟前
240. 搜索二维矩阵 II
python·leetcode·矩阵
LDG_AGI1 小时前
【人工智能】Transformers之Pipeline(十九):文生文(text2text-generation)
人工智能·python·算法·机器学习·视觉检测·aigc·机器翻译
懷淰メ1 小时前
PyQt5实现植物大战僵尸游戏 包含几十种植物、僵尸 欢迎体验!(附下载地址)
开发语言·python·qt·游戏·pyqt·植物大战僵尸·pvz
青年夏日科技工作者1 小时前
科大讯飞智能体Python SDK接入流程
开发语言·python
一雨方知深秋1 小时前
http增删改查四种请求方式操纵数据库
数据库·git·python·mysql·http·flask·request
喜欢踢足球的老罗1 小时前
也遇到过 PIL Image “image file is truncated“的问题
python·pil