python3基础:操作json

json是java script object notation的缩写,用来存储和交换文本信息,比xml更小/更快/更易解析,易于读写,占用带宽小,网络传输速度快的特性,适用于数据量大,不要求保留原有类型的情况。

json语法规则

数据在名称/值对中
数据用逗号分隔
花括号保存对象
方括号保存数组

json名称/值对

名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值,例:
“firstname”:“json”

json数据类型

数字(整数、浮点数)
字符串(在双引号中)
逻辑值(true或false)
数组(在方括号中)
对象(在花括号中)
null

json对象

在花括号中书写,对象可以包含多个名称/值对,例:
{“firstname”:“jonh”,“lastname”:“Doe”}

json数组

employees是包含三个对象的数组。每个对象代表一条关于某个人名的记录,在方括号中书写,数组可以包含多个对象:
{
“employees”:[
{ “firstName”:“John” , “lastName”:“Doe” },
{ “firstName”:“Anna” , “lastName”:“Smith” },
{ “firstName”:“Peter” , “lastName”:“Jones” }
]
}

python解析json的流程

使用时需要import json导入
json.dumps():将python对象编码为json的字符串
json.loads():将字符串编码为一个python对象
json.dump():将python对象序列化到一个文件,是文本文件,相当于将序列化后的json字符写到一个文件
json.load():从文件反序列表出python对象
总结:不带s的是序列化到文件或者从文件反序列化,带s的都是内存操作不涉及持久化

json.dumps()

将一个Python数据类型列表编码成json格式的字符串

#python的列表转换为json的数组
>>> import json
>>> json.dumps([1,2,3])
'[1, 2, 3]'
#python的字符串转换为json的字符串
>>> json.dumps('abdcs')
'"abdcs"'
#python的元祖转换为json的数组
>>> json.dumps((1,2,3,'a'))
'[1, 2, 3, "a"]'#注意此时显示的是方括号
#python的字典转换为json的对象
>>> json.dumps({1:'a',2:'b'})
'{"1": "a", "2": "b"}'#注意此时1和2转换后是加了引号的,因为json的名称是必须要加引号的
#python的整数转换为json的数字
>>> json.dumps(13)
'13'
#python的浮点数转换为json的数字
>>> json.dumps(3.1415)
'3.1415'
#python的unicode字符串转换为json的字符串
>>> json.dumps(u'a')
'"a"'
#python的True转换为json的数组true
>>> json.dumps(True)
'true'
#python的False转换为json的数组false
>>> json.dumps(False)
'false'
#python的None转换为json的null
>>> json.dumps(None)
'null'
#json本质上是一个字符串
>>> type(json.dumps('abc'))

python类型和json类型的对应关系

根据以上输出结果会发现Python对象被转成JSON字符串以后,跟原始的数据类型相比会有些特殊的变化,原字典中的元组被改成了json类型的数组。在json的编码过程中,会存在从Python原始类型转化json类型的过程,但这两种语言的类型存在一些差异,对照表如下:
python3基础:操作json_第1张图片
代码示例:Python类型与json类型示例比对

#coding=utf-8
import json
a = [{1:12,"a":12.3}, [1,2,3],(1,2), "asd", "ad", 12,13,3.3,True, False, None]
print("Python类型:\n", a)
print("编码后的json串:\n", json.dumps(a))

python3基础:操作json_第2张图片

如何判断一个json是否合法

import json
try:
##      json.loads('"abc"')
      json.loads('''abc''')
except Exception as e:
      print (e)
else:
      print('ok')

json.dumps()函数参数的使用

help(“json.dumps”)查看文档,函数原型:

dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

该方法返回编码后的一个json字符串,是一个str对象encodedjson。dumps函数的参数很多,下面只说明几个比较常用的参数。

sort_keys

是否按字典排序(a到z)输出,默认编码成json格式字符串后,是紧凑输出,并且也没有顺序的,不利于可读。sort_keys等于True表示升序
代码示例:

import json
data=[{'a':'A','x':(2,4),'c':3.0}]
print (json.dumps(data))
print (json.dumps(data,sort_keys=True))

输出结果
在这里插入图片描述

indent

根据数据格式缩进显示,读起来更清晰,indent的数值表示缩进的位数
代码示例:

import json
data=[{'a':'A','x':(2,4),'c':3.0}]
print (json.dumps(data,sort_keys=True,indent=3))

python3基础:操作json_第3张图片

separators

去掉逗号“,”和冒号“:”后面的空格。从上面的结果中可以看出‘, :’后面都有个空格,这都是为了美化的作用,但是在传输的过程中,越精简越好,冗余的东西去掉,因此就可以加上separators参数对传输的json串进行压缩。该参数是元组格式的。
代码示例:

import json
data=[{'a':'A','b':(2,4),'c':3.0}]
print (json.dumps(data))
print (json.dumps(data,separators=(',',':')))

在这里插入图片描述

shipkeys

在encoding的过程中,dict的对象只能是基本数据类似(int,float,bool,None,str),如果是其它类型,那么在编码的过程中就会抛出ValueError异常。shipkeys可以跳过那些非string对象的key的处理,就是不处理。
代码示例

#coding=utf-8
import json
data= [ { 'a':'A', 'b':(2, 4), 'c':3.0,(1,2):'D tuple'} ]
try:
      res=json.dumps(data)#skipkeys参数默认为False时
except Exception as e:
      print (e)
print(u"设置skipkeys 参数")
print (json.dumps(data,skipkeys=True)))

在这里插入图片描述

ensure_ascii

表示编码使用的字符集,默认是True,表示使用ascii码进行编码。如果设置为False,就会以Unicode进行编码。由于解码json字符串时返回的就是Unicode字符串,所以可以直接操作Unicode字符,然后直接编码Unicode字符串,这样会简单些。
代码示例

import json
print (json.dumps('凉凉'))
print (json.dumps('凉凉',ensure_ascii=False))

在这里插入图片描述

default:将类对象编码成Json串

Python中的dict对象可以直接序列化为json的{},但是很多时候,可能用class表示对象,比如定义Employe类,然后直接去序列化就会报错。原因是类不是一个可以直接序列化的对象,但我们可以使用dumps()函数中的default参数来实现,由两种方法:

  1. 在类内部定义一个obj_json 方法将对象的属性转换成dict,然后再被序列化为json。
  2. 通过__dict__属性,通常class及其实例都会有一个__dict__属性(除非类中添加了__slots__属性),它是一个dict类型,存储的是类或类实例中有效的属性

代码示例1:通过类中的方法实现

import json
class Employee(object):
      def __init__(self,name,age,sex,tel):
            self.name=name
            self.age=age
            self.sex=sex
            self.tel=tel
      #将序列化函数定义到类中
      def obj_json(self,obj_instance):
            return{
            'name':obj_instance.name,
            'age':obj_instance.age,
            'sex':obj_instance.sex,
            'tel':obj_instance.tel
            }
emp=Employee('kongsh',28,'female',13123456789)
print (json.dumps(emp,default=emp.obj_json))

在这里插入图片描述
代码示例2:通过类的__dict__属性实现

import json
class Employee(object):
      def __init__(self,name,age,sex,tel):
            self.name=name
            self.age=age
            self.sex=sex
            self.tel=tel

emp=Employee('kongsh',18,'female',13123456789)
print (emp.__dict__)
print (json.dumps(emp,default=lambda Employee:Employee.__dict__))
print (json.dumps(emp,default=lambda emp:emp.__dict__))

在这里插入图片描述

json.loads()

将json的字符串解码成python对象

>>> json.loads('{"a":"b"}')#外面用单引号
{'a': 'b'}
>>> json.loads('{"2":1}')
{'2': 1}
>>> a=json.loads('{"1":{"a":"b"}}')
>>> a
{'1': {'a': 'b'}}

json转换为python

由以上输出可以看出编码过程中,Python中的list和tuple都被转化成json的数组,而解
码后,json的数组最终被转化成Python的list的,无论是原来是list还是tuple。
python3基础:操作json_第4张图片
代码示例:从json到Python的类型转化

#coding=utf-8
import json
a = [{1:12, 'a':12.3}, [1,2,3], (1,2), 'asd', 'ad', 12, 13, 3.3, True, False, None]
print(u"编码前\n", a)
print(u"编码后\n", json.dumps(a))
print(u"解码后\n", json.loads(json.dumps(a)))

python3基础:操作json_第5张图片
注意:
json格式的字符串解码成Python对象以后,String类型都变成了Unicode类型,数组变成了list,不会回到原来的元组类型,字典key的字符类型也被转成Unicode类型

json反序列化为对象

json反序列化为类对象或者类的实例,使用的是loads()方法中的object_hook参数
代码示例:

import json
class Employee(object):
      def __init__(self,name,age,sex,tel):
            self.name=name
            self.age=age
            self.sex=sex
            self.tel=tel
emp=Employee('kongsh',18,'female',13123456789)
def jsonToClass(emp):
      return Employee(emp['name'], emp['age'], emp['sex'], emp['tel'])

json_str='{"name": "kongsh", "age": 18, "sex": "female", "tel": 13123456789}'

e=json.loads(json_str,object_hook=jsonToClass)
print (e)
print(e.name)

在这里插入图片描述

你可能感兴趣的:(python)