Python 进阶语法:JSON

1 什么是 JSON?

1.1 JSON 的定义

  • JSON 是 JavaScript Object Notation 的简写,字面上的意思是 JavaScript 对象标记。
  • 本质上,JSON 是轻量级的文本数据交换格式。轻量级,是拿它与另一种数据交换格式XML进行比较,相当轻量简洁。数据交换格式,说明JSON是一种数据格式。
  • 字符串是JSON的一个表现形式,符合JSON格式的字符串就是JSON字符串。
  • JSON 独立于语言:JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。
  • JSON 解析器和 JSON 库支持许多不同的编程语言。 JSON 可以和每一种语言下面特定的一种数据结构进行交换。如 JSON 数据对象可以转换成 Python 里的字典(dict)。

1.2 JSON 的优势

XML 在 JSON 出现之前,是一个主流的数据交换格式,大部分互联网上的服务,它们之间交换数据的时候都采用XML的格式。但是自从轻量级的 JSON 出现了之后,使用 XML 的越来越少了。

  • 易于阅读:XML稍显复杂,看起来的时候比较费劲,但是 JSON 数据就很容易,一看就能知道它是什么意思。
  • 易于解析:JSON 作为了一个数据交换格式,存在一个组装和被解析的过程,这也是强于 XML 的地方,它更容易被解析出来。
  • 网络传输效率高:由于JSON 比较轻量简洁,所以,对于同样一个信息,JSON 的数据量更少一些,在网络上传输的效率更高一些。
  • 跨语言交换数据:JSON 独立于语言和平台,非常简单和轻易地实现跨语言数据交换。

1.3 JSON 的数据结构

1.3.1 对象:大括号 {} 保存的对象是一个无序的名称/值对集合。
{ "name":"Alice", "age":18, "hight":null }
  •  JSON 对象在大括号 {...} 中书写。
  • 对象可以包含多个 key/value(键/值)对。
  • 每个 key/value 对使用逗号 , 分割。
  • key 和 value 中使用冒号 : 分割。
  • key 必须是字符串(在双引号中),value 可以是合法的 JSON 数据类型(字符串(在双引号中), 数字(整数或浮点数), 对象(在大括号中), 数组(在中括号中), 布尔值或 null)。
1.3.2 数组:中括号 [] 保存的数组是值(value)的有序集合。
  •  JSON 数组在中括号中 [...] 书写。
  • JSON 中数组值必须是合法的 JSON 数据类型(字符串, 数字, 对象, 数组, 布尔值或 null)。
  • 数组可包含多个对象。对象属性的值可以是一个数组。
{
    "sites": [
        { "name":"菜鸟教程" , "url":"www.runoob.com" }, 
        { "name":"google" , "url":"www.google.com" }, 
        { "name":"微博" , "url":"www.weibo.com" }
    ]
}
  • JSON 对象中数组可以包含另外一个数组,或者另外一个 JSON 对象
myObj = {
    "name":"网站",
    "num":3,
    "sites": [
        { "name":"Google", "info":[ "Android", "Google 搜索", "Google 翻译" ] },
        { "name":"Runoob", "info":[ "菜鸟教程", "菜鸟工具", "菜鸟微信" ] },
        { "name":"Taobao", "info":[ "淘宝", "网购" ] }
    ]
}

2 Python的内置模块JSON

在Python中,用我们已知的一些内置数据类型,如列表、字典、元组、集合来操作数据结构会比直接操作JSON字符串要方便和简单的多。

JSON是可以跨语言和平台的,与语言无关的。每一个JSON字符串都可以每个语言里面找到一个对应的数据结构。

在Python中,提供了一个内置模块JSON,这个模块有一系列的方法来帮助我们操作JSON数据。

2.1 反序列化

在编程里面,有一个术语,叫反序列化。用来定义由字符串到某一种语言下面的某一种数据结构的解析过程。

2.1.1 使用 json.loads() 把JSON对象字符串转换成 Python 字典
import json

json_str = '{"name":"Alice","age":18}'

student = json.loads(json_str)

print(type(student))   # 返回:<class 'dict'>,说明json.loads()返回的是一个字典
print(student)   # 返回:{'name': 'Alice', 'age': 18}
print(student['name'])  # 返回:Alice
print(student['age'])   # 返回:18

这个 JSON 字符串在 JavaScript 里面表示的是一个 JSON 对象,但是,在 Python 里面它变成了一个字典。

对于同样的这样的一个 JSON 字符串,不同的语言,有可能把 JSON 字符串会变成不同的数据类型,怎么理解呢?我们在 Python 里面,确实是把这样的一个 JSON 字符串转换成了一个字典类型,但是,其他的一些语言有可能不是把它转成这样的一个字典类型,有可能会把它转换成另外的数据结构,比如哈希列表等等,这个呢,都是不一定的。

JSON 字符串对应到 JSON 数据结构里面,它表示的是 JSON 的一个对象。但是,它转换到Python 里面来的时候,是用一个字典的方式来承载 JSON 对象所表示的信息。

在 JSON 数据格式里面啊,它并不仅仅只有 JSON 对象(object)这一种数据类型。它还有数组(array)。

2.1.2 使用 json.loads() 把 JSON 数组字符串转换成 Python 列表
import json

json_str = '[{"name":"Alice","age":18},{"name":"John","age":20}]'

student = json.loads(json_str)
print(type(student))   # 返回:<class 'list'>,说明json.loads()返回的是一个列表
print(student)   # 返回:[{'name': 'Alice', 'age': 18}, {'name': 'John', 'age': 20}]

这个 JSON 字符串在 JavaScript 里面表示的是一个 JSON 数组,但是,在 Python 里面它变成了一个含有两个字典的列表。

为什么这个列表的内部元素是两个字典呢?这是与 JSON 字符串相对应的,JSON 字符串是一个数组,对应 Python 的列表,数组内部是两个 JSON对象,所以对应 Python 的是两个字典。

2.1.3 布尔值的转换
import json

json_str = '[{"name":"Alice","flags":false},{"name":"John","flags":true}]'

student = json.loads(json_str)
print(type(student))   # 返回:<class 'list'>,说明json.loads()返回的是一个列表
print(student)   # 返回:[{'name': 'Alice', 'flags': False}, {'name': 'John', 'flags': True}]

上例中,我们把 JSON 字符串中的数据 flags 的值改成一个布尔值。在 JSON 数据格式里面,布尔值是小写的 false 或者 true 。注意:布尔值不是字符串,我们不需要加双引号。

我们注意一下在 Python 中解析出来的结果:小写的 false 和 true 转换成了首字母大写的 False 和 True 。

2.1.4 本节小结

举了这么多事例呢,无非是想告诉大家,JSON 有自己的一些数据类型。而我们用 json.loads()函数最主要做的一件事情,就是把 JSON 的数据类型转化成 Python 自己的数据类型。

JSON和Python之间的数据类型对比
数据类型JSONPython
字符串JSON中的字符串必须是双引号(")包围的。Python中的字符串可以使用单引号(')或双引号(")包围。
数字JSON支持整数和浮点数Python中的数字类型更加丰富,包括整数(int)、浮点数(float)、复数(complex)等
布尔值JSON支持truefalse两个布尔值。Python使用TrueFalse表示布尔值(注意大小写)。
数组/列表JSON使用数组(array)来表示一组有序的值。Python使用列表(list)来表示一组有序的元素。
对象/字典JSON使用对象(object)来表示键值对的集合。Python使用字典(dict)来表示键值对的集合。
null值JSON有一个null值,表示空或不存在的值。Python使用None来表示空或不存在的值。
其他数据Python还支持更多的数据类型,如元组(tuple)、集合(Set)、日期时间等,而JSON则没有这些数据类型。

上面的内容给大家演示了 JSON 的数据类型到 Python 数据类型的转换方法,就是使用 json.loads(),但是,要强调的是上面所讲的重点并不是介绍如何使用 json.loads() ,关键是想要告诉大家这样的一个 JSON 和 Python 之间的转换关系,这一点比我们会使用 json.loads() ,要重要的太多了。

2.2 序列化

序列化就是把 Python 的数据类型向 JSON 数据类型转换的一个过程。它同样是调用了 JSON 模块下面的一个函数 json.dumps() 。

2.2.1 使用 json.dumps() 把 Python 列表转换成 JSON 数组字符串
import json

# 把Python列表转换成JSON字符串
python_list = [
                {'name':'Alice','age':'18','flags':False},
                {'name':'John','age':'20'}
              ]

json_string = json.dumps(python_list)
print(type(python_list))    # <class 'list'>,这里是python的一个列表
print(type(json_string))    # <class 'str'>,这里是一个JSON字符串
print(json_string)
# 返回一个JSON数组
# [{"name": "Alice", "age": "18", "flags": false}, {"name": "John", "age": "20"}]

在这段代码中,我们使用 Python 的 JSON 模块将 Python 列表(python_list)转换成了 JSON 格式的字符串(json_string)。这个过程主要涉及到 json.dumps() 函数,该函数的作用是将Python 对象(如列表、字典等)序列化成 JSON 格式的字符串。

  1. Python列表:python_list是一个Python列表,其中包含两个字典。每个字典都代表一个人的信息,包括名字(name)、年龄(age)和标志(flags)。
  2. json.dumps()函数:json.dumps()函数用于将Python对象转换(或称为“序列化”)为JSON格式的字符串。这个函数非常有用,当你需要将Python数据结构与JSON格式相互转换时。

    • python_list作为参数传递给json.dumps()
    • 函数遍历python_list中的每个元素(在这里是字典),并将它们转换为JSON格式。
    • 在转换过程中,字典的键和字符串值被直接转换,而整数和布尔值也被相应地转换。
    • 转换后的JSON字符串被赋值给json_string变量。
  3. 类型检查:python_list的类型是<class 'list'>,表示它是一个Python列表。而json_string的类型是<class 'str'>,表示它是一个字符串,即JSON格式的字符串。

  4. 打印JSON字符串:输出的结果是一个JSON数组,其中包含两个对象(对应于原始Python列表中的两个字典)。

注意点:

  • 在JSON中,所有的键和字符串值都必须用双引号(")包围,而不是单引号(')。
  • Python中的布尔值False在JSON中表示为false(全部小写)。
  • Python中的整数和浮点数在转换为JSON时不会改变,但Python中的字符串(即使是数字形式的字符串)在JSON中仍然被视为字符串。例如,年龄'18''20'在JSON中仍然是字符串,而不是数字。

通过这个过程,我们可以方便地在 Python 和 JSON 之间转换数据,这对于与Web服务交互或存储和读取数据非常有用。这就叫做序列化。

这里要跟大家强调一下,并不是和 JSON 相关的这样一系列的转化才叫做序列化,如果我们把 XML的字符串向 Python 的数据结构转换,或者,把 Python 的数据结构向 XML字符串转换,它这个过程也称为序列化或者反序列化。

(小提示:怎样把一个对象存储到数据库里去呢?

数据库是一个二维表,它没有办法去表示一个对象的结构。所以,一个方法就是把对象序列化成JSON 字符串或者 XML字符串。然后把字符串存到这个数据库里去。

当你要需要这个对象的时候,可以把这个字符串从数据库里读出来,然后再进行反序列化的过程。但是,实际上这个是不可取的,因为效率太低了。这个办法在操作数据库或者是其他类型的数据库,还是比较适合去存储一些比较简单的数据结构。

而像对象这种东西,应该把对象拆成一个二维表结构,也就是说把对象分成一个个的属性,把它存到这数据库里会比较合适。强烈反对把对象给序列化之后,以字符串的形式存储到数据库里。)

2.2.2 序列化的意义

上一节,我们写了一个 JSON 字符串,然后把它给反序列化成了 Python 字典。但是,我们要考虑的是这个 JSON 字符串是从哪里来的呢?

这不太可能是我们自己一个一个地写出来的。其实,一般情况下这个 JSON 字符串还是我们通过序列化的过程来的。有可能是通过其他语言序列化之后,通过一个服务的形式传给我们的。

下面举一个比较实际的例子,比如:

  • 通过豆瓣的API(https://api.douban.com/v2/movie/top250)服务,获取一个JSON字符串。

{
"msg":"invalid_apikey, Please contact bd-team@douban.com for authorized access.",
"code":104,
"request":"GET \/v2\/movie\/top250"
}
  • 拿到 JSON 字符串,就可以把它变成 Python 里面的数据结构,从而获取到 JSON 字符串里面的相关数据信息

从这个事例可以看到:为什么说 JSON 是一个数据交换的格式呢?我们可以明显的看到这个数据是从豆瓣的服务这里以 JSON 数据格式的形式,传送到我们自己的浏览器。既然是数据,它就必然要有一个承载的格式。大多数情况都是选择用 JSON 数据格式来传递数据。

3 对 JSON 理解上的误区

JSON、JSON对象、JSON字符串这三者的区别,如果在网上搜一搜,说法各种各样、五花八门,不能说它错,但并不全面。

网上对于这三者的解释都没有跳出 JavaScript 这样的一个范围,都是站在 JavaScript 这个特定语言的角度阐述这三者的区别。所以,我们要跳出语言的范畴来看待这三个不同的名词。

3.1 JSON 并不是为 JavaScript 量身定制的

因为 JSON 的数据交换和 JavaScript 是没有什么区别的,很多人很容易会认为 JavaScript 很特殊,它和 JSON 是有一些特殊关系的。

其实没有,那么造成这种误区的原因?可能有两个方面:

第一个方面是 JSON数据类型和JavaScript 的数据类型太过于相似。所以,很多人一直搞不清楚 JSON 和 JavaScript 的关系。

JavaScript 和 JSON 之间的关系:JavaScript这个语言它只是一个标准的实现方案之一,这个标准就是EcmaScript。还有以前写flash程序的时候,有个ActionScript。这个其实也是实现这个EcmaScript 标准的另外一种语言。我们可以把 JSON 也理解为是实现 EcmaScript 标准的一个的版本。

JSON 并不是JavaScript的一个附属品,这一点呢,大家一定要清楚。所以,某种程度上来说,JSON 可以看作是和 JavaScript 平齐的一种语言。因为 JSON 和JavaScript 都是对 EcmaScript 这个规范和标准的实现。

第二个方面是 JSON最开始的时候,在外部前后端分离的过程中起到了重要的作用。而我们服务器的语言有很多很多种,但是前端里边,现在最主流的就是一个JavaScript。因为 JSON 被大量的应用于JavaScript的交互中,所以会让很多人产生这样的一个误区。

3.2 JSON对象确实存在,但它的定义非常片面

那么对应到三个名词上面,JSON字符串、JSON,我们不再说了。我们重点要说的是这个JSON对象。JSON对象确实存在,但它的定义非常片面。

片面在什么地方呢?如果把JSON对象放到JavaScript里面来说的话呢?JSON对象这个说法是成立的,但是问题是:如果跳出了这个JavaScript的范畴,比如说放到Phthon里面,其实是没有JSON对象这个说法的啊。所以,如果你在搜索引擎里面去搜索JSON字符串和JSON对象的区别,绝大多数的答案都是以 JavaScript 这个语言为蓝本的。

3.3  JSON 我们应该把它理解成一个中间的语言格式

JSON 是一个比较独立的数据类型。它和 JavaScript 没有特定的关系。跳出语言层面,如果我们要实现在两种不同的语言之间传递数据:

第一种情况:世界上只有两种语言,我们可以直接按照一定的规则,把A语言的数据类型转换成B语言的数据类型就可以了,JSON没有存在的必要。

第二种情况:显然,第一种情况是不存在的,目前已经有许多种语言,要实现两两之间的转换,就需要写若干种规则,这显然也是不靠谱的,这时就需要有一种中间类型的语言(或者一种中间的数据类型的格式)来作为一个标准,所有的语言都向这个中间数据类型来转换,这样就可以实现不同语言之间的快速转换。

所以,很多时候,我们应该把它理解成是一个中间的数据类型的转换格式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/400070.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

矩阵通课程,帮助你全方位学习搭建新媒体矩阵的技巧

从选择平台、确定矩阵布局&#xff0c;到打造运营团队、制定内容策略、复盘矩阵运营&#xff0c;矩阵通为企业带来新媒体矩阵建设全攻略&#xff0c;助力企业从零起步搭建矩阵。 了解课程详细内容&#xff0c;也可前往“新榜矩阵通”服务号查看。

Android轻量级进程间通信Messenger源码分析

一. 概述 Android中比较有代表性的两大通信机制&#xff1a;1. 线程间Handler通信 2. 进程间Binder通信&#xff0c;本篇文章中我们在理解AIDL原理的基础上来解读一下Messenger的源代码&#xff0c; 并结合示例Demo加深理解。 在看本篇文章前&#xff0c;建议先查阅一下笔者的…

Golang - 从源码到二进制:探索在国产CPU架构上交叉编译Minio的方法

文章目录 前置知识交叉编译Go 支持的所有操作系统和体系结构组合列出 Go 支持的所有操作系统和体系结构组合 大端、小端minio使用的go版本ABI 官方下载目标编译loongarch架构下的minio编译mipsle架构下的minio编译sw64架构下的minio 前置知识 交叉编译 交叉编译是指在一台主机…

ComfyUI 基础教程(十二):AI换脸神器 InstantID ComfyUI, 保姆级安装与使用测评

AI换脸技术发展迅速,roop,Reactor,ipadapter-faceid,photomaker,InstantID,换脸神器更新非常快。 对比lora训练,faceID,intantID,IPA,在人脸风格的迁移上,是目前AI换脸的主要方式。而最新出的InstantID,只需单个图像即可实现ID保留生成,相似度极高。 instantid特…

springboot项目之java.lang.NullPointerException: null问题

没有任何提示&#xff0c;只有一行报错: RuntimeException-[java.lang.NullPointerException] 问题定位: 最后发现是 controller文件&#xff0c;service定义一行少加了关键字 final 导致的&#xff0c; 补充之后就完美解决啦&#xff01; 参考 springboot项目之java.lang.Nu…

基于vue的个性化推荐餐饮系统Springboot

项目&#xff1a;基于vue的个性化推荐餐饮系统Springboot 摘要 现代信息化社会下的数据管理对活动的重要性越来越为明显&#xff0c;人们出门可以通过网络进行交流、信息咨询、查询等操作。网络化生活对人们通过网上购物也有了非常大的考验&#xff0c;通过网上进行点餐的人也…

软件实例分享,饭店餐饮会员卡管理系统怎么弄会员充值怎么记账

软件实例分享&#xff0c;饭店餐饮会员卡管理系统怎么弄会员充值怎么记账 一、前言 以下软件教程以 佳易王餐饮会员管理系统软件V16为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、会员可以登记电子会员卡或使用vip卡片 2、卡类型可以自由…

SICTF Round#3 Web方向 题解WP

100&#xff05;_upload 题目描述&#xff1a;小茂夫说&#xff1a;一直上传恶意文件尊嘟要生气了&#xff0c;世事莫固守&#xff0c;转变思路求突破 开题&#xff0c;注意有个文件包含 题目把后缀过滤死了&#xff0c;无法上传php后缀文件。文件内容些许过滤&#xff0c;短…

微信小程序uniapp校园在线报修系统维修系统java+python+nodejs+php

管理员的主要功能有&#xff1a; 1.管理员输入账户登陆后台 2.个人中心&#xff1a;管理员修改密码和账户信息 3.用户管理&#xff1a;对注册的用户信息进行删除&#xff0c;查询&#xff0c;添加&#xff0c;修改 4.维修工管理&#xff1a;对维修工信息进行添加&#xff0c;修…

【递归】【后续遍历】【迭代】【队列】Leetcode 101 对称二叉树 100. 相同的树

【递归】【后续遍历】Leetcode 101 对称二叉树 100 相同的树 101. 对称二叉树解法一&#xff1a; 递归&#xff1a;后序遍历 左右中解法二&#xff1a; 迭代法&#xff0c;用了单端队列 100. 相同的树解法一&#xff1a;深度优先 ---------------&#x1f388;&#x1f388;对称…

关于Windows 11中的Microsoft Defender,看这篇就差不多了

Windows内置的安全应用程序Microsoft Defender可保护你的计算机免受恶意代理和病毒的攻击。然而,在某些情况下,你可能想要禁用它,例如在测试第三方安全应用程序时。我们将向你展示如何在Windows 11上永久禁用Microsoft Defender。 何时应永久禁用Microsoft Defender防病毒 …

vue3前端excel导出;组件表格,自定义表格导出;Vue3 + xlsx + xlsx-style

当画面有自定义的表格或者样式过于复杂的表格时&#xff0c;导出功能可以由前端实现 1. 使用的插件 &#xff1a; sheet.js-xlsx 文档地址&#xff1a;https://docs.sheetjs.com/ 中文地址&#xff1a;https://geekdaxue.co/read/SheetJS-docs-zh/README.md xlsx-style&#…

【8】证书公钥替换

0x01 问题描述 存在一个前置系统&#xff0c;数据包有登录信息。登录需要填入用户名&#xff0c;证书上传&#xff0c;私钥。如图&#xff1a; 提供数据包如下&#xff1a; POST /api/certLogin HTTP/1.1 Host: 192.168.11.153 Connection: keep-alive Content-Length: 934…

srs集群下行edge处理逻辑

官方关于源站集群的介绍&#xff1a; Origin Cluster | SRS 下行边缘是指观众端从边缘edge拉流&#xff0c;边缘edge回源到源站origin节点拉流&#xff0c;然后再 把流转给客户端 边缘处理类SrsPlayEdge 当服务器收到播放请求时&#xff0c;创建对应的consumer消费者。在创…

【保真】揭秘目前唯一能使用Sora的官方渠道 —— OpenAI Red Teaming Network

原文链接&#xff1a;【保真】揭秘目前唯一能使用Sora的官方渠道 —— OpenAI Red Teaming Network 前几天OpenAI推出的Sora模型着实太火了&#xff0c;不仅让圈内人热血封腾&#xff0c;也给圈外人点了一把AGI的热情之火。 Sora的大火&#xff0c;也有不少小伙伴开始问一个问…

2.网络游戏逆向分析与漏洞攻防-游戏启动流程漏洞-项目搭建

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;1.网络游戏逆向分析与漏洞攻防-游戏启动流程漏洞-测试需求与需求拆解-CSDN博客 代码以提交到码云&#xff1a;https://gitee.com/dye_your_fingers/titan 开始搭建环境 创建之前&#xff1a;HOOK引擎…

集成厂家服务的核心内容

一、关系定义 集成商是指将多个不同的产品或服务集成在一起&#xff0c;形成一个整体解决方案&#xff0c;满足客户需求的企业或个人。 厂家产品商是指生产和销售产品的企业或个人&#xff0c;他们制造和提供各种产品&#xff0c;供集成商使用。 客户关系是指集成商和厂家产…

爬虫在网页抓取的过程中可能会遇到哪些问题?

在网页抓取&#xff08;爬虫&#xff09;过程中&#xff0c;开发者可能会遇到多种问题&#xff0c;以下是一些常见问题及其解决方案&#xff1a; 1. IP封锁&#xff1a; 问题&#xff1a;封IP是最常见的问题&#xff0c;抓取的目标网站会识别并封锁频繁请求的IP地址。 解决方案…

git push 使用 --mirror 参数复制仓库

迁移一个 Git 仓库并且保留原有的提交记录和分支 克隆原始仓库到本地 git clone <原始仓库URL> <新仓库目录>添加新的远程仓库&#xff1a;git remote add new-origin <新仓库URL>推送所有分支和标签到新的远程仓库&#xff1a;git push new-origin --mirro…

Vue封装全局公共方法

有的时候,我们需要在多个组件里调用一个公共方法,这样我们就能将这个方法封装成全局的公共方法。 我们先在src下的assets里新建一个js文件夹,然后建一个common.js的文件,如下图所示: 然后在common.js里写我们的公共方法,比如这里我们写了一个testLink的方法,然后在main…