如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如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()
方法返回一个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可以将转换后的json字符串写入文件
import json
a = {'name':'lucy','age':18}
file = open('./person.txt','w')
json.dump(a,file)
file.close()
可以将json转换为python对象
import json
a = json.loads('{"name": "lucy", "age": 18}')
print(a)
print(type(a))
'''
{'name': 'lucy', 'age': 18}
<class 'dict'>
'''
可以将json文件,转换为python对象
import json
file = open('./person.txt','r')
a = json.load(file)
print(a)
file.close()
'''
{'name': 'lucy', 'age': 18}
'''
由于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}
'''