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的实用指南的更多相关文章

  1. python学习之路-day4-装饰器&json&pickle

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 一.生成器 1.列表生成式 >>> L = [x * x for x in range(10 ...

  2. JSON取代XML?--JSON入门指南

    定义 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C# ...

  3. 《Android Studio实用指南》7.1 AndroidStudio代码检查工具概述

    本文节选自<Android Studio实用指南> 作者: 毕小朋 目前本书已上传到百度阅读, 在百度中搜索[Anroid Studio实用指南]便可以找到本书. Android Stud ...

  4. 推荐几个IDEA插件,Java开发者撸码利器(转载)

    推荐几个IDEA插件,Java开发者撸码利器.   这里只是推荐一下好用的插件,具体的使用方法不一一详细介绍. JRebel for IntelliJ 一款热部署插件,只要不是修改了项目的配置文件,用 ...

  5. 阿里巴巴泰山版《Java 开发者手册》,也是一份防坑指南

    我是风筝,公众号「古时的风筝」,一个不只有技术的技术公众号,一个在程序圈混迹多年,主业 Java,另外 Python.React 也玩儿的 6 的斜杠开发者. Spring Cloud 系列文章已经完 ...

  6. 100个高质量Java开发者博客

    ImportNew注:原文中还没有100个.作者希望大家一起来推荐高质量的Java开发博客,然后不段补充到这个列表.欢迎你也参与推荐优质的Java开发博客.(声明一下:我们的数学不是体育老师教的!:) ...

  7. 转:100个高质量Java开发者博客

    原文来自于:http://www.importnew.com/7469.html ImportNew注:原文中还没有100个.作者希望大家一起来推荐高质量的Java开发博客,然后不段补充到这个列表.欢 ...

  8. 【伯乐在线】100个高质量Java开发者博客

    本文由 ImportNew - 夏千林 翻译自 programcreek.欢迎加入翻译小组.转载请见文末要求. ImportNew注:原文中还没有100个.作者希望大家一起来推荐高质量的Java开发博 ...

  9. python模块之pickle、shelve、json

    一 什么是序列化 序列化指的是将内存中的数据结构转化为一种中间格式,并存储到硬盘上. (反序列化:将硬盘上存储的中间格式数据再还原为内存中的数据结构) 二 为什么要序列化 持久保持状态 需知一个软件/ ...

  10. JAVA开发者大会:拍拍贷MQ系统原理与应用

    --喜欢记得关注我哟[shoshana]-- 前记: 5月12号参加了JAVA开发者大会,就<拍拍贷消息系统原理及应用> 作者:李乘胜老师 关于PMQ的分享整理一下笔记以及笔记的思考 和复 ...

随机推荐

  1. python操作mongodb基本使用

    使用pymongo,具体可以参考官方文档: 语法上基本和原生mongodb是一样的,所以非常容易入手... https://pymongo.readthedocs.io/en/stable/tutor ...

  2. 【UniApp】-uni-app-处理项目输入数据(苹果计算器)

    前言 上一篇文章完成了项目的基本布局,这一篇文章我们来处理一下项目的输入数据 项目的输入数据主要是通过按键来输入的,所以我们需要对按键进行处理 那么我们就来看一下 uni-app-处理项目输入数据 步 ...

  3. LLaMA大型语言模型

    LLaMA (Large Language Model Meta AI)是Meta公司发布的大型语言模型系列,近日LLaMA种子文件被合并到了GitHub 上,同时一些项目维护者给予了批准,目前该项目 ...

  4. 文心一言 VS 讯飞星火 VS chatgpt (55)-- 算法导论6.3 1题

    文心一言 VS 讯飞星火 VS chatgpt (55)-- 算法导论6.3 1题 一.参照图6-3 的方法,说明 BUILD-MAX-HEAP在数组 A=(5,3,17,10,84,19,6,22, ...

  5. 常见的Java中SQL注解的用法

    @Select:用于查询操作,标注在方法上,指定相应的SQL查询语句. @Select("SELECT * FROM table_name WHERE condition") Li ...

  6. ChatGPT新玩法来了,微信聊天机器人

    前言 上一篇文章中说了ChatGPT是什么,然后怎么注册使用. 传送门:花了1块钱体验一把最近很火的ChatGPT 但是实际操作下来还是有不少小伙伴跟我一样遇到各种坑. 没有魔法工具 OpenAI的服 ...

  7. Java 将Excel工作簿按工作表拆分为多个文档

    本文介绍在Java代码环境中如何将Excel工作簿按工作表拆分为多个Excel文档,即:把Excel工作簿中的每一个工作表单独保存为一个Excel工作簿文件. 思路及方法:通过将源文档中的每个工作表通 ...

  8. FQS:一种神奇的数仓查询优化技术

    本文分享自华为云社区<根据执行计划优化SQL[绽放吧!GaussDB(DWS)云原生数仓]>,作者:西岭雪山. 引言 如果您刚接触DWS那一定会好奇想要知道"REMOTE_FQS ...

  9. 详解CCE服务:一站式告警配置和云原生日志视图

    本文分享自华为云社区<新一代云原生可观测平台之CCE服务日志和告警篇>,作者:云容器大未来. 告警和日志是运维人员快速定位问题.恢复异常的主要手段.运维人员日常的工作模式往往是先接收告警信 ...

  10. CSV:简单格式下隐藏的那些坑

    摘要:本文将盘点处理CSV数据时我遇到的一些坑. 本文分享自华为云社区<CSV-简单格式下隐藏的那些坑>,作者:aKi. 前言 CSV(Comma-Separated Values),是一 ...