9、json

Json

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下

JSON类型 Python类型
{} dict
[] list
"string" str
1234.56 int或float
true/false True/False
null None

Python内置的json模块提供了非常完善的Python对象到JSON格式的转换

dumps

dumps()方法返回一个str,内容就是标准的JSON

json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding="utf-8", default=None, sort_keys=False, **kw)

obj:就是你要转化成json的对象。

sort_keys =True:是告诉编码器按照字典排序(a到z)输出。如果是字典类型的python对象,就把关键字按照字典排序。

indent:参数根据数据格式缩进显示,读起来更加清晰,None为不缩进,数值为缩进的空格数

separators:是分隔符的意思,参数意思分别为不同dict项之间的分隔符和dict项内key和value之间的分隔符,把:和,后面的空格都除去了。

skipkeys:默认值是False,如果dict的keys内的数据不是python的基本类型(str,unicode,int,long,float,bool,None),设置为False时,就会报TypeError的错误。此时设置成True,则会跳过这类key 。

ensure_ascii:默认输出ASCLL码,如果把这个该成False,就可以输出中文。

check_circular:如果check_circular为false,则跳过对容器类型的循环引用检查,循环引用将导致溢出错误(或更糟的情况)。

allow_nan:如果allow_nan为假,则ValueError将序列化超出范围的浮点值(nan、inf、-inf),严格遵守JSON规范,而不是使用JavaScript等价值(nan、Infinity、-Infinity)。

default:default(obj)是一个函数,它应该返回一个可序列化的obj版本或引发类型错误。默认值只会引发类型错误。

import json

a = {'name':'lucy','age':18}

str = json.dumps(a)

print(str)

'''
{"name": "lucy", "age": 18}
'''

dump

dump可以将转换后的json字符串写入文件

import json

a = {'name':'lucy','age':18}

file = open('./person.txt','w')
json.dump(a,file)
file.close()

loads

可以将json转换为python对象

import json

a = json.loads('{"name": "lucy", "age": 18}')

print(a)
print(type(a))

'''
{'name': 'lucy', 'age': 18}
<class 'dict'>
'''

load

可以将json文件,转换为python对象

import json

file = open('./person.txt','r')

a = json.load(file)

print(a)

file.close()

'''
{'name': 'lucy', 'age': 18}
'''

自定义类型-JSON

由于python和json之间的互相转换只限制于python内置基本数据类型,对于自定义的数据类型,如果使用dumps进行转换,会抛出TypeError;但是dumps函数有一个形参default,这个参数需要传一个函数,函数需要可以将该对象转为python数据类型,并返回,例如dict字典

import json

class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

def person2json(per):
    "将person对象转为dict"
    return {
        'name':per.name,
        'age':per.age
    }

person = Person('lucy',18)

str = json.dumps(person,default=person2json)
print(str)

'''
{"name": "lucy", "age": 18}
'''

通常class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量。也有少数例外,比如定义了__slots__的class,所以我们可以不用给每个对象都写一个转dict的函数

import json

class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

person = Person('lucy',18)

str = json.dumps(person,default=lambda per : per.__dict__)
print(str)

'''
{"name": "lucy", "age": 18}
'''