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

相关推荐
DLYSB_5 小时前
存储运维实战:基于 Ceph Event 监听与 Python 适配器的分布式存储健康度物理声光响应架构
运维·ceph·python·报警灯
陈随易5 小时前
FFmpeg 9.0 发布,代号 Lei,音视频处理再升级
前端·后端·程序员
阿童木写作5 小时前
跨境图片翻译工具多合一,批量图片视频字幕翻译加智能抠图
人工智能·python·音视频·语音识别
阿童木写作6 小时前
Python实现Temu图片批量翻译自动化教程
运维·人工智能·python·自动化
就是一只白8 小时前
复制地理信息python版本
python
凌虚8 小时前
面向 MySQL 用户的 PostgreSQL 快速上手指南
数据库·后端·架构
看浪的路人8 小时前
第1讲:Agent 到底是什么?和 Chatbot 有什么区别
python·ai
瓦学妹9 小时前
什么是网络索引?它是如何工作的?
大数据·网络·python·网络爬虫
IT_陈寒9 小时前
Vite静态资源引用这个坑我踩得有点疼
前端·人工智能·后端
天天爱吃肉82189 小时前
商用车多体动力学实战笔记|第6篇:动力传动系统(发动机、变速箱、分动器、TCS、LSD限滑差速)
大数据·人工智能·笔记·python·嵌入式硬件·汽车