【摘要】本博文介绍了何为json模块?为何要用json模块?json和python数据的相互转换以及如何处理json默认不支持的数据类型。
1. json模块简介
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。在json出现之前,不同语言之前的数据交换使用的是xml。
JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、Java、JavaScript、Perl、Python等)。
这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。
所以,JSON的数据我们可以将其转换为其他编程语言支持的数据类型,本博文就讲解JSON与python的数据交换。
2. python数据转换为json数据类型
python转换为JSON数据格式的转换规则
python 中str类型到JSON中转为unicode类型,None转为null,dict对应object;
特别要【注意】pyhton中的集合不能转成json格式。
函数 | 描述 |
json.dumps | 将python对象序列化成JSON字符串 |
json.dump | 将python对象序列化并保存到json文件中 |
json.dump( )和json.dumps( )是完全不同的。
json.dump( )是对json文件的读写操作,而json.dumps( )是对json数据的操作。
【补充】
序列化(编码): python对象编码成json字符串
反序列化(解码): 将json字符串转成python对象
json.dumps( )
下面我们就用代码实现一下:
我们先创建一个python的users字典
users = {}
for item in range(50):
users['user%s' %(item)] = 'potizo'
我们现在要做的是把这个python下的字典转换为json对象。
import json
json_users = json.dumps(users)
#这里为了友好显示,调用了pprint模块的pprint方法
pprint.pprint(json_users)
print('dumps之后的类型',type(json_users))
可以看到,对users字典调用了json.dumps之后,其类型为json字符串。
通过ctrl+点击dumps函数,我们进去看一下这个函数如何使用,都有什么参数可以传?
这里总结一下我们常用的几个形参:
indent=4 ---------------------------------缩进为4
#有了缩进就增强了可读性,但是缩进空格会使数据变大
ensure_ascii=False--------------------如果显示中文需要设置
separators=None --------------------- 修改默认分隔符#分隔符的设置应该是(‘元素分隔符’,‘key-value分隔符’)这样的元组,默认值是(‘,’ , ‘,’)
sort_keys ----- ------------------------ 对字典的key值进行排序
我们看一下,加了这些参数之后的效果:
import json
json_users = json.dumps(users, indent=4, ensure_ascii=False, separators=(';', '-'), sort_keys=True)
print(json_users)
可以看到我们并没有调用pprint,但是这个字符串的显示却通过我们的传值缩进了4格;ensure_ascii=False由于这个字典中不含中文,所以没有显示效果;key-value之间的分隔符是‘-’,而每个元素之间的分隔是;
再看一下ensure_ascii=False和sort_keys=True的效果
json_users = json.dumps(users, indent=4, ensure_ascii=False, separators=(';', '-'), sort_keys=True)
中文帮我们显示了,并且排序为0、1、11…19、2、21…29
json_users = json.dumps(users, indent=4, separators=(';', '-'))
没有显示出中文,而是显示的其文字对应的unicode编码,并且排序为0、1、2、3…10、11
json.dump( )
将python对象编码为json格式的字符串, 并保存到指定文件中
with open('doc/users.json', 'w') as f:
json.dump(users, f, indent=4, ensure_ascii=False)
3. json数据转换为python数据类型
json转换为python’数据格式的转换规则
函数 | 描述 |
json.loads( ) | 将序列化的json字符串反序列化为python对象 |
json.load( ) | 将序列化字符串从文件读取并反序列化 |
json.loads( )
loads( )函数的形参与dumps不同,dumps()是编码与loads()是解码
with open('doc/users.json') as f:
content = f.read()
user_obj = json.loads(content)
print(user_obj)
print('loads之后的类型',type(user_obj))
loads()与load()用法不同,但是也可以实现从json文件中读取字符串保存到内存中,再将其解码为python对象。
load()
with open('doc/users.json') as f:
user_obj = json.load(f)
print(user_obj)
print('load之后的类型:',type(user_obj))
4.自定义复杂数据类型编解码
通过上面2张图片,我们可以看到python与json数据的相互转换规则中也存在一些数据类型无法转换。比如我们碰到集合对象, datetime对象,或者自定义的类对象等json默认不支持的数据类型时,我们就需要自定义编解码函数。
下面我们就用datetime对象来举例说明,如何实现json与python之间的复杂数据类型转换。
python转json:
import datetime,json
def time2str(obj):
# 用内置函数 isinstance检查数据类型是否是datetime.datetime
if isinstance(obj,datetime.datetime):
#def strftime(self, fmt: _Text) -> str: ...
#strftime可以把datetime.datetime的类型转还为字符串
json_str = {'datetime':obj.strftime('%Y-%m-%d')}
return json_str
return obj
dt = datetime.datetime.now()
#但其实这个函数只是帮我们把datetime对象转换为了python中的字典
pyDt = time2str(dt)
print(type(pyDt),pyDt)
若要转换为json格式,还需要dumps()
jsonDt = json.dumps(pyDt)
print(type(jsonDt),jsonDt)
json转python:
def str2time(jsonObj):
#判断json对象中是否含有datetime这个子串
if 'datetime' in jsonObj:
#如果存在,拿出这个datetime对应的value值
date_str = jsonObj['datetime']
#用列表生成式将年月日的值转为整型
date = [int(x) for x in date_str.split('-')]
#然后调用函数生成datetime对象
dt = datetime.datetime(date[0].date[1].date[2])
return dt
return jsonObj
pyDt = json.loads(jsonDt,objetc_hook=str2time)
print(type(pyDt),pyDt)
后面的时分秒是因为jsonDt中没有,所以解析不出来。如果需要时分秒。。。
看代码吧:
在time2str()函数中,加上%X
json_str = {'datetime':obj.strftime('%Y-%m-%d %X')}
在str2time()函数中,注意以下几行需要修改
date_str,time_str = jsonObj['datetime'].split(' ')
date = [int(x) for x in date_str.split('-')]
time = [int(x) for x in time_str.split(':')]
dt = datetime.datetime(date[0],date[1],date[2],time[0],time[1],time[2])
效果为: