zoukankan      html  css  js  c++  java
  • 玩转python中json

    1.JSON发展

    2005 年,JSON 有了一次大爆发。那一年,一位名叫 Jesse James Garrett 的网页设计师和开发者在博客文章中创造了 “AJAX” 一词。他很谨慎地强调:AJAX 并不是新技术,而是 “好几种蓬勃发展的技术以某种强大的新方式汇集在一起。” AJAX 是 Garrett 给这种正受到青睐的 Web 应用程序的新开发方法的命名。他的博客文章接着描述了开发人员如何利用 JavaScript 和 XMLHttpRequest 构建新型应用程序,这些应用程序比传统的网页更具响应性和状态性。他还以 Gmail 和 Flickr 网站已经使用 AJAX 技术作为了例子。

    当然了,“AJAX” 中的 “X” 代表 XML。但在随后的问答帖子中,Garrett 指出,JSON 可以完全替代 XML。他写道:“虽然 XML 是 AJAX 客户端进行数据输入、输出的最完善的技术,但要实现同样的效果,也可以使用像 JavaScript Object Notation(JSON)或任何类似的结构数据方法等技术。”

    这时JSON便在国外的博客圈、技术圈慢慢流行起来!2006 年,Dave Winer,一位高产的博主,他也是许多基于 XML 的技术(如 RSS 和 XML-RPC)背后的开发工程师,他抱怨到 JSON 毫无疑问的正在重新发明 XML。Crockford 阅读了 Winer 的这篇文章并留下了评论。为了回应 JSON 重新发明 XML 的指责,Crockford 写到:“重造轮子的好处是可以得到一个更好的轮子”。

    2.JSON实例

    还是以上面A、B公司业务对接为例子,两边的开发人员协商一种通用的数据交换格式,现在有XML与JSON比较流行的两种数据格式,于是开发人员又将用户信息以JSON形式展现出来,然后比较两种数据格式。

    {  "person": {    "name": "pig",    "age": "18",    "sex": "man",    "hometown": {      "province": "江西省",      "city": "抚州市",      "county": "崇仁县"    }  }}

    比较XML与JSON的数据格式之后,开发人员发现:JSON可阅读性、简易性更好而且相同数据负载JSON字符数更少,所以两个开发人员一致同意使用JSON作为接口数据格式!

    而且还有重要的一点,在编写XML时,第一行需要定义XML的版本,而JSON不存在版本问题,格式永远不变!

    3.当今JSON地位

    当今的JSON 已经占领了全世界。绝大多数的应用程序彼此通过互联网通信时,都在使用 JSON。它已被所有大型企业所采用:十大最受欢迎的 web API 接口列表中(主要由 Google、Facebook 和 Twitter 提供),仅仅只有一个 API 接口是以 XML 的格式开放数据的。JSON 也在程序编码级别和文件存储上被广泛采用:在 Stack Overflow上,关于JSON的问题越来越多,下图是关于Stack Overflow上不同数据交换格式的问题数和时间的曲线关系图。

    从上图我们可以看出在Stack Overflow上越来越多JSON的问题,从这里也可以反映出JSON越来越流行!

    更详细的关于JSON的故事可阅读:https://www.jianshu.com/p/62a856367d2d

    今天我们来学习一下JSON的结构形式、数据类型、使用场景以及注意事项吧!目录:

    一、JSON格式

        1.JSON的2种结构形式

        2.JOSN的6种数据类型

    二、JSON使用场景

        1.接口返回数据

        2.序列化

        3.生成Token

        4.配置文件

    三、JSON在Python中的使用

        1.类型转换

        2.对应的数据类型

        3.需要注意的点

    四、总结

    一、JSON格式

    上面我们知道JSON是从JavaScript的数据类型中提取出来的子集,那JSON有几种结构形式呢?又有哪些数据类型呢?他们又分别对应着JavaScript中的哪些数据类型呢?

    1.JSON的2种结构形式

    1、键值对形式

    上期我们举了一个JSON的实例,就是键值对形式的,如下:

    {  "person": {    "name": "pig",    "age": "18",    "sex": "man",    "hometown": {      "province": "江西省",      "city": "抚州市",      "county": "崇仁县"    }  }}

    这种结构的JSON数据规则是:一个无序的“‘名称/值’对”集合。一个对象以 {左括号 开始, }右括号 结束。每个“名称”后跟一个 :冒号 ;“‘名称/值’ 对”之间使用 ,逗号 分隔


    2、数组形式

    因为大多数的时候大家用的JSON可能都是上面那种key-value形式,所以很多人在讲解JSON的时候总是会忽略数组形式,这一点是需要注意的。那JSON的数组形式是怎么样的呢?举一个实例吧!

    ["pig", 18, "man", "江西省抚州市崇仁县"]

    数组形式的JSON数据就是值(value)的有序集合。一个数组以 [左中括号 开始, ]右中括号 结束。值之间使用 ,逗号 分隔。

    2.JOSN的6种数据类型

    上面两种JSON形式内部都是包含value的,那JSON的value到底有哪些类型,而且上期我们说JSON其实就是从Js数据格式中提取了一个子集,那具体有哪几种数据类型呢?

    1. string:字符串,必须要用双引号引起来。

    2. number:数值,与JavaScript的number一致,整数(不使用小数点或指数计数法)最多为 15 位,小数的最大位数是 17

    3. object:JavaScript的对象形式,{ key:value }表示方式,可嵌套。

    4. array:数组,JavaScript的Array表示方式[ value ],可嵌套。

    5. true/false:布尔类型,JavaScript的boolean类型。

    6. null:空值,JavaScript的null。

    以上数据形式图片来源JSON官方文档:http://www.json.org/json-zh.html

    二、JSON使用场景

    介绍完JSON的数据格式,那我们来看看JSON在企业中使用的比较多的场景。

    1.接口返回数据

    JSON用的最多的地方莫过于Web了,现在的数据接口基本上都是返回的JSON,具体细化的场景有:

    1. Ajxa异步访问数据
    2. RPC远程调用
    3. 前后端分离后端返回的数据
    4. 开放API,如百度、高德等一些开放接口
    5. 企业间合作接口


    这种API接口一般都会提供一个接口文档,说明接口的入参、出参等,


    一般的接口返回数据都会封装成JSON格式,比如类似下面这种

     

    2.序列化

    程序在运行时所有的变量都是保存在内存当中的,如果出现程序重启或者机器宕机的情况,那这些数据就丢失了。

    一般情况运行时变量并不是那么重要丢了就丢了,但有些内存中的数据是需要保存起来供下次程序或者其他程序使用。

    保存内存中的数据要么保存在数据库,要么保存直接到文件中,而将内存中的数据变成可保存或可传输的数据的过程叫做序列化

    在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

    正常的序列化是将编程语言中的对象直接转成可保存或可传输的,这样会保存对象的类型信息,而JSON序列化则不会保留对象类型

    为了让大家更直观的感受区别,用代码做一个测试,大家一目了然

    1. Python对象直接序列化会保存class信息,下次使用loads加载到内存时直接变成Python对象。
    2. JSON对象序列化只保存属性数据,不保留class信息,下次使用loads加载到内存可以直接转成dict对象,当然也可以转为Person对象,但是需要写辅助方法。


    对于JSON序列化不能保存class信息的特点,那JSON序列化还有什么用?

    答案是当然有用,对于不同编程语言序列化读取有用,

    比如:我用Python爬取数据然后转成对象,现在我需要将它序列化磁盘,然后使用Java语言读取这份数据,这个时候由于跨语言数据类型不同,所以就需要用到JSON序列化。

    存在即合理,两种序列化可根据需求自行选择!

    3.生成Token

    首先声明Token的形式多种多样,有JSON、字符串、数字等等,只要能满足需求即可,没有规定用哪种形式。

    JSON格式的Token最有代表性的莫过于JWT(JSON Web Tokens)。



    随着技术的发展,分布式web应用的普及,通过Session管理用户登录状态成本越来越高,

    因此慢慢发展成为Token的方式做登录身份校验,然后通过Token去取Redis中的缓存的用户信息,

    随着之后JWT的出现,校验方式更加简单便捷化,无需通过Redis缓存,

    而是直接根据Token取出保存的用户信息,以及对Token可用性校验,单点登录更为简单。


    我也曾经使用JWT做过app的登录系统,大概的流程就是:

    1. 用户输入用户名密码
    2. app请求登录中心验证用户名密码
    3. 如果验证通过则生成一个Token,其中Token中包含:用户的uid、Token过期时间、过期延期时间等,然后返回给app
    4. app获得Token,保存在cookie中,下次请求其他服务则带上
    5. 其他服务获取到Token之后调用登录中心接口验证
    6. 验证通过则响应


    JWT登录认证有哪些优势:

    1. 性能好:服务器不需要保存大量的session

    2. 单点登录(登录一个应用,同一个企业的其他应用都可以访问):使用JWT做一个登录中心基本搞定,很容易实现。

    3. 兼容性好:支持移动设备,支持跨程序调用,Cookie 是不允许垮域访问的,而 Token 则不存在这个问题。

    4. 安全性好:因为有签名,所以JWT可以防止被篡改。


    更多JWT相关知识自行在网上学习,本文不过多介绍!

    4.配置文件

    说实话JSON作为配置文件使用场景并不多,最具代表性的就是npm的package.json包管理配置文件了,下面就是一个npm的package.json配置文件内容。

    但其实JSON并不合适做配置文件,因为它不能写注释、作为配置文件的可读性差等原因。

    配置文件的格式有很多种如:toml、yaml、xml、ini等,目前很多地方开始使用yaml作为配置文件格式。

    三、JSON在Python中的使用

    最后我们来看看Python中操作JSON的常用方法有哪些,在Python中操作JSON时需要引入json标准库。

    import json

    1.类型转换

    1、Python类型转JSON:json.dump()

    # 1、Python的dict类型转JSON
    person_dict = {'name': 'pig', 'age': 18, 'sex': 'man', 'hometown': '江西抚州'}
    # indent参数为缩进空格数
    person_dict_json = json.dumps(person_dict, indent=4)
    print(person_dict_json, ' ')
    # 2、Python的列表类型转JSON
    person_list = ['pig', 18, 'man', '江西抚州']
    person_list_json = json.dumps(person_list)
    print(person_list_json, ' ')
    # 3、Python的对象类型转JSON
    person_obj = Person('pig', 18, 'man', '江西抚州')
    # 中间的匿名函数是获得对象所有属性的字典形式
    person_obj_json = json.dumps(person_obj, default=lambda obj: obj.__dict__, indent=4)
    print(person_obj_json, ' ')

    执行结果:

    2、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), ' ')
    # 5、JSON转Python的列表类型
    person_json2 = '["pig", 18, "man", "江西抚州"]'
    person_json_list = json.loads(person_json2)
    print(type(person_json_list), ' ')
    # 6、JSON转Python的自定义对象类型
    person_json = '{ "name": "pig","age": 18, "sex": "man", "hometown": "江西抚州"}'
    # object_hook参数是将dict对象转成自定义对象
    person_json_obj = json.loads(person_json, object_hook=lambda d: Person(d['name'], d['age'], d['sex'], d['hometown']))
    print(type(person_json_obj), ' ')

    执行结果如下:

    2.对应的数据类型

    上面我们演示了Python类型与JSON的相互转换,最开始的时候我们讲过JSON有6种数据类型,那这6种数据类型分别对应Python中的哪些数据类型呢?

    3.需要注意的点

      1. JSON的键名和字符串都必须使用双引号引起来,而Python中单引号也可以表示为字符串,所以这是个比较容易犯的错误!
      2. Python类型与JSON相互转换的时候到底是用load/dump还是用loadsdumps
      3. 他们之间有什么区别?什么时候该加s什么时候不该加s
      4. 这个我们可以通过查看源码找到答案:
      5. 不加s的方法入参多了一个fp表示filepath,最后多了一个写入文件的操作
      6. 所以我们在记忆的时候可以这样记忆:

      7. Python自定义对象与JSON相互转换的时候需要辅助方法来指明属性与键名的对应关系,如果不指定一个方法则会抛出异常!
      8. 相信有些看的仔细的同学会好奇上面使用json.dumps方法将Python类型转JSON的时候,如果出现中文,则会出现:u6c5fu897fu629au5dde这种东西,这是为什么呢?原因是:

        Python 3中的json在做dumps操作时,会将中文转换成unicode编码,并以16进制方式存储,而并不是UTF-8格式!

  • 相关阅读:
    IntelliJ IDEA自动补全变量名称和属性名称的快捷键
    Redis客户端 Spring Data Redis(未完)
    用画小狗的方法来解释Java中的值传递
    Java -- Arrays.asList()方法
    有趣的IntegerCache
    字符串使用点滴
    字符串拼接+和concat的区别
    在一个Excel单元格内输入多行内容
    JSTL1.2学习总结
    Android ico
  • 原文地址:https://www.cnblogs.com/fcc-123/p/12040699.html
Copyright © 2011-2022 走看看