翼度科技»论坛 编程开发 python 查看内容

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

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
JSON

JSON作为目前最流行的传输格式,在Python中也有相应的实现方式。由于JSON格式的文本可以跨平台并且简单易用,因此被广泛传播。因此,我们今天的主要讨论内容是如何熟练地应用Python的JSON库来处理将JSON映射到文本,以及如何从文本映射到对象中。现在,让我们开始探讨这个话题。
官方json库

在Python中,官方提供了多个JSON库,包括标准库中的json、marshal和pickle。其中,我个人比较喜欢使用json库,因为pickle存在一些反序列化漏洞,并且它处理的是二进制类型的数据。相比之下,json更类似于我们在Java中使用的fastjson,但它们之间仍然存在一些明显的差异。接下来,我们继续深入了解一下。
简单用法
  1. import json
  2. json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
  3. # '["foo", {"bar": ["baz", null, 1.0, 2]}]'
  4. print(json.dumps(""foo\bar"))
  5. # ""foo\bar"
  6. print(json.dumps('\u1234'))
  7. # "\u1234"
  8. print(json.dumps('\\'))
  9. # "\"
  10. print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
  11. # {"a": 0, "b": 0, "c": 0}
  12. from io import StringIO
  13. io = StringIO()
  14. json.dump(['streaming API'], io)
  15. io.getvalue()
  16. # '["streaming API"]'
复制代码
上面提到的是官方提供的一些JSON库的示例,我们不再深入讨论。现在,让我们来讲解一下在工作中如何使用JSON进行对象的序列化和反序列化。
进阶用法

当前端返回给后端一串JSON文本时,我们可以使用json.loads()方法将其正确映射到Python对象中。这个过程称为反序列化。使用对象来处理数据会更规范一些,尽管对于一些快速开发来说,直接使用字典可能更方便。不过,我可以给你演示一下如何使用对象进行反序列化。
首先,我们可以定义一个类来表示我们要映射的对象,然后利用json.loads()方法将JSON文本转换为字典。接着,我们可以使用字典的键值对来为对象的属性赋值。这样,我们就成功地将JSON文本映射到了对象中。让我来给你演示一下:
{"status":1,"info":"成功","data":{"id":"52","age":"70"}}
上面是我们接收的参数,我们需要对其进行处理,将其映射到相应的对象中。
  1. import json
  2. class Response_data:
  3.     def __init__(self, id, feed_id):
  4.         super().__init__()
  5.         self.id = id
  6.         self.feed_id = feed_id
  7. class Response:
  8.     def __init__(self, status=None, info=None, data=None) -> None:
  9.         super().__init__()
  10.         self.status = status
  11.         self.info = info
  12.         self.data = data
  13.     def to_json(self):
  14.         return {
  15.             "status": self.status,
  16.             "info": self.info,
  17.             "data": self.data.__dict__ if self.data else None
  18.         }
  19.     @staticmethod
  20.     def object_hook(d):
  21.         if "status" in d :
  22.             return Response(d['status'], d['info'], d['data'])
  23.         else:
  24.             return Response_data(d['id'],d['feed_id'])
  25. body = '{"status":1,"info":"发布成功","data":{"id":"52","feed_id":"70"}}'
  26. resp = json.loads(body, object_hook=Response.object_hook)
  27. 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 的类型对照表:
JSONPythonobjectdictarrayliststringunicodenumber (int)int, longnumber (real)floattrueTruefalseFalsenullNone三方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模块的示例代码:
  1. from dataclasses import dataclass
  2. @dataclass
  3. class Person:
  4.     name: str
  5.     age: int
  6. # 假设您有一个包含 JSON 数据的字符串
  7. json_data = '{"name": "xiaoyu", "age": 18}'
  8. # 使用 orjson 反序列化 JSON 数据
  9. import orjson
  10. data_dict = orjson.loads(json_data)
  11. # 将字典转换为 Person 对象
  12. person = Person(**data_dict)
  13. # 现在,您可以像访问对象属性一样访问 person 对象的属性
  14. print(person.name)  # 输出 "xiaoyu"
  15. print(person.age)   # 输出 18
复制代码
经过仔细观察,我发现这两种方式看起来确实非常相似,官方的JSON模块也能实现相同的功能。但是当我们尝试将person对象转换成字符串时,官方的JSON模块无法完成这个任务,而orjson则可以轻松胜任。
  1. orjson.dumps(person)
复制代码
option参数

orjson还支持使用option参数来定制序列化的结果。当然,还有很多其他的选项可以使用,但是由于太多了,我就不一一列举了。不过,我可以简单举一个日期格式的例子,因为在我们的工作中,通常需要对日期格式进行处理。
option=orjson.OPT_OMIT_MICROSECONDS: 序列化的日期时间对象将以字符串形式呈现,而不是默认的 ISO 8601 格式。这个选项在某些情况下可能更加便利,尤其是在与其他系统进行数据交换时。通过使用该选项,您可以确保日期时间对象的格式与其他系统的要求相匹配,从而简化数据交换的过程。
  1. import orjson
  2. from datetime import datetime
  3. data = {"name": "xiaoyu", "dob": datetime(2020, 5, 1)}
  4. json_data = orjson.dumps(data, option=orjson.OPT_OMIT_MICROSECONDS)
  5. 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数据。

来源:https://www.cnblogs.com/guoxiaoyu/p/17975802
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具