责编 | maozz
JSON的诞生原因是因为XML整合到HTML中各个浏览器实现的细节不尽相同,所以道格拉斯·克罗克福特(Douglas Crockford) 和 奇普·莫宁斯达(Chip Morningstar)一起从JS的数据类型中提取了一个子集,作为新的数据交换格式,因为主流的浏览器使用了通用的JavaScript引擎组件,所以在解析这种新数据格式时就不存在兼容性问题,于是他们将这种数据格式命名为 “JavaScript Object Notation”,缩写为 JSON,由此JSON便诞生了!今天我们来学习一下JSON的结构形式、数据类型、使用场景以及注意事项吧!
JSON格式上面我们知道JSON是从JavaScript的数据类型中提取出来的子集,那JSON有几种结构形式呢?又有哪些数据类型呢?他们又分别对应着JavaScript中的哪些数据类型呢?JSON的2种结构形式,键值对形式和数组形式。举了一个JSON的实例,就是键值对形式的,如下:{“person”:{“name”:”pig”,”age”:”18″,”sex”:”man”,”hometown”:{“province”:”江西省”,”city”:”抚州市”,”county”:”崇仁县”}}}这种结构的JSON数据规则是:一个无序的“‘名称/值’对”集合。一个对象以 {左括号 开始, }右括号 结束。每个“名称”后跟一个 :冒号 ;“‘名称/值’ 对”之间使用 ,逗号 分隔。
因为大多数的时候大家用的JSON可能都是上面那种key-value形式,所以很多人在讲解JSON的时候总是会忽略数组形式,这一点是需要注意的。那JSON的数组形式是怎么样的呢?举一个实例吧![“pig”,18,”man”,”江西省抚州市崇仁县”]数组形式的JSON数据就是值(value)的有序集合。一个数组以 [左中括号 开始, ]右中括号 结束。值之间使用 ,逗号 分隔。
JOSN的6种数据类型上面两种JSON形式内部都是包含value的,那JSON的value到底有哪些类型,而且上期我们说JSON其实就是从Js数据格式中提取了一个子集,那具体有哪几种数据类型呢?string:字符串,必须要用双引号引起来。number:数值,与JavaScript的number一致,整数(不使用小数点或指数计数法)最多为 15 位,小数的最大位数是 17。object:JavaScript的对象形式,{ key:value }表示方式,可嵌套。array:数组,JavaScript的Array表示方式[ value ],可嵌套。true/false:布尔类型,JavaScript的boolean类型。null:空值,JavaScript的null。
JSON使用场景介绍完JSON的数据格式,那我们来看看JSON在企业中使用的比较多的场景。接口返回数据和序列化。JSON用的最多的地方莫过于Web了,现在的数据接口基本上都是返回的JSON,具体细化的场景有:Ajxa异步访问数据RPC远程调用前后端分离后端返回的数据开放API,如百度、高德等一些开放接口企业间合作接口这种API接口一般都会提供一个接口文档,说明接口的入参、出参等,
一般的接口返回数据都会封装成JSON格式,比如类似下面这种{“code”:1,”msg”:”success”,”data”:{“name”:”pig”,”age”:”18″,”sex”:”man”,”hometown”:{“province”:”江西省”,”city”:”抚州市”,”county”:”崇仁县”}}}程序在运行时所有的变量都是保存在内存当中的,如果出现程序重启或者机器宕机的情况,那这些数据就丢失了。一般情况运行时变量并不是那么重要丢了就丢了,但有些内存中的数据是需要保存起来供下次程序或者其他程序使用。保存内存中的数据要么保存在数据库,要么保存直接到文件中,而将内存中的数据变成可保存或可传输的数据的过程叫做序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。正常的序列化是将编程语言中的对象直接转成可保存或可传输的,这样会保存对象的类型信息,而JSON序列化则不会保留对象类型!为了让大家更直观的感受区别,猪哥用代码做一个测试,大家一目了然
Python对象直接序列化会保存class信息,下次使用loads加载到内存时直接变成Python对象。JSON对象序列化只保存属性数据,不保留class信息,下次使用loads加载到内存可以直接转成dict对象,当然也可以转为Person对象,但是需要写辅助方法。
对于JSON序列化不能保存class信息的特点,那JSON序列化还有什么用?答案是当然有用,对于不同编程语言序列化读取有用,比如:我用Python爬取数据然后转成对象,现在我需要将它序列化磁盘,然后使用Java语言读取这份数据,这个时候由于跨语言数据类型不同,所以就需要用到JSON序列化。存在即合理,两种序列化可根据需求自行选择!最后就是生成Token和配置文件首先声明Token的形式多种多样,有JSON、字符串、数字等等,只要能满足需求即可,没有规定用哪种形式。JSON格式的Token最有代表性的莫过于JWT(JSON Web Tokens)。
随着技术的发展,分布式web应用的普及,通过Session管理用户登录状态成本越来越高,因此慢慢发展成为Token的方式做登录身份校验,然后通过Token去取Redis中的缓存的用户信息,随着之后JWT的出现,校验方式更加简单便捷化,无需通过Redis缓存,而是直接根据Token取出保存的用户信息,以及对Token可用性校验,单点登录更为简单。
但其实JSON并不合适做配置文件,因为它不能写注释、作为配置文件的可读性差等原因。配置文件的格式有很多种如:toml、yaml、xml、ini等,目前很多地方开始使用yaml作为配置文件格式。
JSON在Python中的使用最后我们来看看Python中操作JSON的常用方法有哪些,在Python中操作JSON时需要引入json标准库。importjson
类型转换
Python类型转JSON:json.dump()#1、Python的dict类型转JSONperson_dict={‘name’:’pig’,’age’:18,’sex’:’man’,’hometown’:’江西抚州’}#indent参数为缩进空格数person_dict_json=json.dumps(person_dict,indent=4)print(person_dict_json,’\n’)#2、Python的列表类型转JSONperson_list=[‘pig’,18,’man’,’江西抚州’]person_list_json=json.dumps(person_list)print(person_list_json,’\n’)#3、Python的对象类型转JSONperson_obj=Person(‘pig’,18,’man’,’江西抚州’)#中间的匿名函数是获得对象所有属性的字典形式person_obj_json=json.dumps(person_obj,default=lambdaobj:obj.__dict__,indent=4)print(person_obj_json,’\n’)
执行结果:
JSON转Python类型:json.loads()#4、JSON转Python的dict类型person_json='{“name”:”pig”,”age”:18,”sex”:”man”,”hometown”:”江西抚州”}’person_json_dict=json.loads(person_json)print(type(person_json_dict),’\n’)#5、JSON转Python的列表类型person_json2='[“pig”,18,”man”,”江西抚州”]’person_json_list=json.loads(person_json2)print(type(person_json_list),’\n’)#6、JSON转Python的自定义对象类型person_json='{“name”:”pig”,”age”:18,”sex”:”man”,”hometown”:”江西抚州”}’#object_hook参数是将dict对象转成自定义对象person_json_obj=json.loads(person_json,object_hook=lambdad:Person(d[‘name’],d[‘age’],d[‘sex’],d[‘hometown’]))print(type(person_json_obj),’\n’)
执行结果如下:
对应的数据类型上面我们演示了Python类型与JSON的相互转换,最开始的时候我们讲过JSON有6种数据类型,那这6种数据类型分别对应Python中的哪些数据类型呢?
需要注意的点JSON的键名和字符串都必须使用双引号引起来,而Python中单引号也可以表示为字符串,所以这是个比较容易犯的错误!Python类型与JSON相互转换的时候到底是用load/dump还是用loads\dumps?他们之间有什么区别?什么时候该加s什么时候不该加s?这个我们可以通过查看源码找到答案:不加s的方法入参多了一个fp表示filepath,最后多了一个写入文件的操作。所以我们在记忆的时候可以这样记忆:加s表示转成字符串(str),不加s表示转成文件。
Python自定义对象与JSON相互转换的时候需要辅助方法来指明属性与键名的对应关系,如果不指定一个方法则会抛出异常!
相信有些看的仔细的同学会好奇上面使用json.dumps方法将Python类型转JSON的时候,如果出现中文,则会出现:\u6c5f\u897f\u629a\u5dde这种东西,这是为什么呢?原因是:Python 3中的json在做dumps操作时,会将中文转换成unicode编码,并以16进制方式存储,而并不是UTF-8格式!