python 中的 json 库使用
文章目录
- json模块
- 序列化概念
- json标准库
- 基本用法
- json.dumps()
- json.loads()
- json.dump()
- json.load()
- 类的序列化
- 无法序列化问题
json模块
序列化概念
- 我们平常使用的python对象所进行的操作是在内存中,当程序关闭就会被清空,所以我们需要用一种合适的方法将这些数据保存下来;
- 为了将我们的数据进行永久存储,需要引入序列化(pickling/serialization)的概念;
- 序列化的定义:将复杂的python数据结果转换成一个二进制数据集合(数据流);
- 反序列化:从数据流(字符串形式)重新构造复杂的python数据结;
- 序列化的好处:我们可以通过网络或本地存储介质讲这些数据流保存或传输;
- 序列化的方法:引入
json
、pickling
、marshal
、shelve
,其中最常用的是json
。
json标准库
基本用法
json
模块的序列化和反序列化方法分别是dumps
和loads
,json.dumps()
和json.dump()
将一个python对象转换成json
串,json.loads()
和json.load()
将一个json
串还原成python
对象。json.dump()
和json.dumps()
的区别
json.dump()
处理的是文件对象,而json.dumps()
处理的是字符串对象。json.load()
和json.loads()
的区别
json.load()
处理的是文件对象,而json.loads()
处理的是字符串对象。
json.dumps()
-
将python的数据类型转换成json字串
语法格式:
json.dumps(obj , skipkeys=False# 是否允许JSON字串编码字典对象时,字典的key不是字符串类型(默认是不允许 , ensure_ascii=True , check_circular=True , allow_nan=True , cls=None , indent=None # 定义缩进大小 , separators=None # 是一个元组,定义分隔符类型 , encoding="utf-8" , default=None , sort_keys=False # 是否排序 , **kw)
>>> import json >>> json.dumps([]) Out[3]: '[]' >>> json.dumps('String') Out[4]: '"String"' >>> json.dumps(1) Out[5]: '1' >>> json.dumps({"name":"tyson","age":23}) Out[6]: '{"name": "tyson", "age": 23}'
使用参数能让JSON字串格式化输出:
>>> print(json.dumps({'a': 'Runoob', 'b': 7}, sort_keys=True, indent=4, separators=(',', ': '))) { "a": "Runoob", "b": 7 }
-
较重要的参数:
sort_keys
:是否排序
indent
:定义缩进大小
separators
:是一个元组,定义分隔符的类型
skipkeys
:是否允许JSON
字串编码字典对象时,字典的key不是字符串类型(默认是不允许)a = ['foo', {'bar': ('baz', None, 1.0, 2)}] s = json.dumps(a , sort_keys=True , indent=4 , separators=('!', '?') ) #分隔符这里只是测试,一般保持默认逗号和分号即可 print(s) [ "foo"! { "bar"?[ "baz"! null! 1.0! 2 ] } ]
import json try: data = {'a': 1, 'b': 2, (1,): 3} json.dumps(data) except TypeError as e: print(e) # keys must be a string print('='*25) print(json.dumps(data, skipkeys=True)) # {"a": 1, "b": 2} print('='*25) data = {'a': 1, 'b': 2, 1: 3} print(json.dumps(data)) result: keys must be a string {"a": 1, "b": 2} {"a": 1, "1": 3, "b": 2}
-
Python 原始类型向json类型的转换对照表
python json dict object list,tuple array str,unicode string int,long,float number True true False false None null
json.loads()
-
将json字串转换成python的数据类型。也就是反序列化。
语法格式:
loads(s , * , encoding=None , cls=None , object_hook=None , parse_float=None , parse_int=None , parse_constant=None , object_pairs_hook=None , **kw):
json.loads('{"a":"Runoob","b":7}') Out[12]: {'a': 'Runoob', 'b': 7}
-
json字串转换成python对象类型对照表
JSON Python object dict array list string unicode number(int) int number(real) float true True false False null
json.dump()
-
将序列化之后形成的JSON字串保存到文件。
语法格式:dump(obj , fp , * , skipkeys=False , ensure_ascii=True , check_circular=True , allow_nan=True , cls=None , indent=None , separators=None , default=None , sort_keys=False , **kw):
import json a = {"name": "tyson", "age": 21, "sex": "boy"} # 第一种方法将JSON字串写入文件中 # 该方法不需要close with open("./save/json.txt", "a") as f: f.write(json.dumps(a, indent=4)) # 第二种方法将JSON字串写入文件中 f = open("./save/json.txt", "a") json.dump(a, f, indent=4) f.close() """json.txt""" { "name": "tyson", "age": 21, "sex": "boy" }{ "name": "tyson", "age": 21, "sex": "boy" }
json.load()
-
从文件接受JSON字串,并反序列化成为Python的数据类型。
语法格式:load(fp , * , cls=None , object_hook=None , parse_float=None , parse_int=None , parse_constant=None , object_pairs_hook=None , **kw):
import json a = {"name": "tyson", "age": 21, "sex": "boy"} # 第一种方法将JSON字串写入文件中 # 该方法不需要close with open("./save/json", "a") as f: f.write(json.dumps(a)) # 第一种方法将文件中的JSON字串转反序列化成Python的数据类型 with open("./save/json", "r") as f: print(json.loads(f.read())) # json {"age": 21, "name": "tyson", "sex": "boy"} result: {'name': 'tyson', 'age': 21, 'sex': 'boy'}
类的序列化
-
类的序列化
"""类的序列化""" import json class student(object): def __init__(self, name, sex, age): self.name = name self.sex = sex self.age = age tyson = student("tyson", "boy", 21) print(json.dumps(tyson, default=lambda obj: obj.__dict__)) # python的JSON想办法能将各种数据对象都转换为JSON,其中可选参数default就是用来提供给用户自行定义转换函数的 # 所以上面的方法与下面这个是等同的 def stuclass2json(classObject): return { 'name': classObject.name, 'sex': classObject.sex, 'age': classObject.age } print(json.dumps(tyson, default=stuclass2json)) result: {"name": "tyson", "sex": "boy", "age": 21} {"name": "tyson", "sex": "boy", "age": 21}
无法序列化问题
-
json.dump()或者json.dumps()无法序列化,报xxx is not JSON serializable的解决方案
import json import numpy as np params = {'1':2,'3':np.arange(10)} json.dump(params,open('./test.txt',mode='w+'),indent=2,ensure_ascii=False) """报错""" TypeError: Object of type ndarray is not JSON serializable
-
创建一个类来继承json.JSONEncoder,重写json.JSONEncoder中的方法,即自定义序列化方法
class NpEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, np.integer): return int(obj) elif isinstance(obj, np.floating): return float(obj) elif isinstance(obj, np.ndarray): return obj.tolist() else: return super(NpEncoder, self).default(obj) json.dump(params ,open('./test.txt',mode='w+') ,indent=2 ,cls =NpEncoder ,ensure_ascii=False )