json是java script object notation的缩写,用来存储和交换文本信息,比xml更小/更快/更易解析,易于读写,占用带宽小,网络传输速度快的特性,适用于数据量大,不要求保留原有类型的情况。
数据在名称/值对中
数据用逗号分隔
花括号保存对象
方括号保存数组
名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值,例:
“firstname”:“json”
数字(整数、浮点数)
字符串(在双引号中)
逻辑值(true或false)
数组(在方括号中)
对象(在花括号中)
null
在花括号中书写,对象可以包含多个名称/值对,例:
{“firstname”:“jonh”,“lastname”:“Doe”}
employees是包含三个对象的数组。每个对象代表一条关于某个人名的记录,在方括号中书写,数组可以包含多个对象:
{
“employees”:[
{ “firstName”:“John” , “lastName”:“Doe” },
{ “firstName”:“Anna” , “lastName”:“Smith” },
{ “firstName”:“Peter” , “lastName”:“Jones” }
]
}
使用时需要import json导入
json.dumps():将python对象编码为json的字符串
json.loads():将字符串编码为一个python对象
json.dump():将python对象序列化到一个文件,是文本文件,相当于将序列化后的json字符写到一个文件
json.load():从文件反序列表出python对象
总结:不带s的是序列化到文件或者从文件反序列化,带s的都是内存操作不涉及持久化
将一个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字符串以后,跟原始的数据类型相比会有些特殊的变化,原字典中的元组被改成了json类型的数组。在json的编码过程中,会存在从Python原始类型转化json类型的过程,但这两种语言的类型存在一些差异,对照表如下:
代码示例: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))
import json
try:
## json.loads('"abc"')
json.loads('''abc''')
except Exception as e:
print (e)
else:
print('ok')
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函数的参数很多,下面只说明几个比较常用的参数。
是否按字典排序(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的数值表示缩进的位数
代码示例:
import json
data=[{'a':'A','x':(2,4),'c':3.0}]
print (json.dumps(data,sort_keys=True,indent=3))
去掉逗号“,”和冒号“:”后面的空格。从上面的结果中可以看出‘, :’后面都有个空格,这都是为了美化的作用,但是在传输的过程中,越精简越好,冗余的东西去掉,因此就可以加上separators参数对传输的json串进行压缩。该参数是元组格式的。
代码示例:
import json
data=[{'a':'A','b':(2,4),'c':3.0}]
print (json.dumps(data))
print (json.dumps(data,separators=(',',':')))
在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)))
表示编码使用的字符集,默认是True,表示使用ascii码进行编码。如果设置为False,就会以Unicode进行编码。由于解码json字符串时返回的就是Unicode字符串,所以可以直接操作Unicode字符,然后直接编码Unicode字符串,这样会简单些。
代码示例:
import json
print (json.dumps('凉凉'))
print (json.dumps('凉凉',ensure_ascii=False))
Python中的dict对象可以直接序列化为json的{},但是很多时候,可能用class表示对象,比如定义Employe类,然后直接去序列化就会报错。原因是类不是一个可以直接序列化的对象,但我们可以使用dumps()函数中的default参数来实现,由两种方法:
代码示例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的字符串解码成python对象
>>> json.loads('{"a":"b"}')#外面用单引号
{'a': 'b'}
>>> json.loads('{"2":1}')
{'2': 1}
>>> a=json.loads('{"1":{"a":"b"}}')
>>> a
{'1': {'a': 'b'}}
由以上输出可以看出编码过程中,Python中的list和tuple都被转化成json的数组,而解
码后,json的数组最终被转化成Python的list的,无论是原来是list还是tuple。
代码示例:从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)))
注意:
json格式的字符串解码成Python对象以后,String类型都变成了Unicode类型,数组变成了list,不会回到原来的元组类型,字典key的字符类型也被转成Unicode类型
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)