Python实现JSON序列化和反序列化
在我的应用中,序列化就是把类转成符合JSON格式的字符串,反序列化就是把JSON格式的字符串转换成类。C#的话直接用Newtonsoft.JSON就可以了,非常好用。本来以为python也会有类似的库,但是貌似并没有。网上查了一些python用来实现JSON序列化和反序列化的方法,用的最多的就是json.loads, json.dumps。
# 序列化:将Python对象转换成json字符串
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字符串转换成Python对象
loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
# 序列化:将Python对象转换成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) # 反序列化:读取指定文件中的json字符串并转换成Python对象
load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
包含自定义类的序列化例子:
from typing import List class Address:
def __init__(self,country,city):
self.country=country
self.city=city class Student:
def __init__(self,name,age,sex,address):
self.name=name
self.age=age
self.sex=sex
self.address=address class School:
def __init__(self,name,address:Address,students:List[Student]):
self.name=name
self.address=address
self.students=students import json addr1=Address('China','Beijing')
stu1=Student('lily',20,'female',Address('China','Shanghai'))
stu2=Student('tom',23,'male',Address('China','Shenzhen'))
sch1=School('MathSchool',addr1,[stu1,stu2]) # 先把python对象转换为dict对象,进而才能实现序列化
json_data=json.dumps(sch1,default=lambda o:o.__dict__,indent=2)
print(json_data)
输出结果为:

{
"name": "MathSchool",
"address": {
"country": "China",
"city": "Beijing"
},
"students": [
{
"name": "lily",
"age": 20,
"sex": "female",
"address": {
"country": "China",
"city": "Shanghai"
}
},
{
"name": "tom",
"age": 23,
"sex": "male",
"address": {
"country": "China",
"city": "Shenzhen"
}
}
]
}
序列化结果
再把生成的json_data反序列化
sch2=School(**json.loads(json_data))
print(type(sch2))
print(type(sch2.students))
print(type(sch2.address))
输出的结果为:
<class '__main__.School'>
<class 'list'>
<class 'dict'>
可见,这样的反序列化无法直接生成School类中的address属性和students属性。address的类型仍为dict,而students的类型是list。因此需要再把address的dict转换为Address,把students的list转换成List[Student]。
sch2=School(**json.loads(json_data))
sch2.address=Address(**json.loads(json.dumps(sch2.address)))
students=[]
for stu in sch2.students:
students.append(Student(**json.loads(json.dumps(stu))))
sch2.students=students
也就是说,要这样才能生成一个完整的School类。总感觉太麻烦了,不像用newtonsoft.json那么方便。于是在网上搜到了Refs[2]这篇帖子,用了里面的方法,其实这个方法就是构造了一个创建类的Structure基类。这个方法对于List[Student]这种属性我依然不能很好的解决,总感觉就差了一点点,但是我python用的没有很熟练,也只能这样了。Structure基类的代码为:
class Structure(object):
_fields=[] def __init_arg(self,expected_type,value):
if isinstance(value,expected_type):
return value
else:
return expected_type(**value) def __init__(self, **kwargs):
field_names,field_types = zip(*self._fields)
assert([isinstance(field_name,str) for field_name in field_names])
assert([isinstance(type_,type)for type_ in field_types]) for field_name,field_type in self._fields:
setattr(self,field_name,self.__init_arg(field_type, kwargs.pop(field_name))) if kwargs:
raise TypeError('Invalid arguments(s):{}'.format(','.join(kwargs)))
继承该类,那么School, Address, Student类分别为:
class Address(Structure):
_fields=[('country',str),('city',str)] class Student(Structure):
_fields=[('name',str),('age',int),('sex',str),('address',Address)] class School(Structure):
_fields=[('name',str),('address',Address),('students',list)]
序列化和反序列化:其中序列化还是使用json,反序列化则没有使用json
import json
addr=Address(**{'country':'China','city':'Beijing'})
stu1=Student(**{'name':'lily','age':18,'sex':'female','address':addr})
stu2=Student(**{'name':'tom','age':19,'sex':'male','address':addr})
sch=School(**{'name':'mathSchool','address':addr,'students':[stu1,stu2]})
# 序列化sch对象,生成字符串
json_data=json.dumps(sch,default=lambda o:o.__dict__,indent=2)
# 将json_data字符串转换为dict
data=json.loads(json_data)
# 反序列化data,得到sch1对象
sch1=School(**data)
# 反序列化可以直接获取到sch1.address对象,但是对于students对象还是不行
print(type(sch1.address))
# list类型的students属性还是要这样生成一下
students=[]
for stu in sch1.students:
students.append(Student(**stu))
sch1.students=students
Refs:
python:序列化与反序列化(json、pickle、shelve) - 秋寻草 - 博客园 (cnblogs.com)
Deserializing nested dictionaries into complex, typed(!) python objects (seanjohnsen.com)
Python实现JSON序列化和反序列化的更多相关文章
- python处理JSON 序列化与反序列化
#序列化 >>> import json>>> d={"key":"value"}>>> d{'key': ...
- 【Python】Json序列化和反序列化模块dumps、loads、dump、load函数介绍
1.json.dumps() json.dumps()用于将dict类型的数据转成str,因为如果直接将dict类型的数据写入json文件中会发生报错,因此在将数据写入时需要用到该函数. 转换案例: ...
- python json序列化与反序列化操作
python json序列化与反序列化操作 # dumps() dict-->str 序列化 # loads() str---dict 反序列化 result1 = json.dumps({'a ...
- python 3 json 序列化
python 3 json 序列化 我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特 ...
- DotNet的JSON序列化与反序列化
JSON(JavaScript Object Notation)JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式.在现在的通信中,较多的采用JSON数据格式,JSON有 ...
- C#中JSON序列化和反序列化
有一段时间没有到博客园写技术博客了,不过每天逛逛博客园中大牛的博客还是有的,学无止境…… 最近在写些调用他人接口的程序,用到了大量的JSON.XML序列化和反序列化,今天就来总结下json的序列化和反 ...
- Newtonsoft.Json 序列化和反序列化 时间格式
From : http://www.cnblogs.com/litian/p/3870975.html 1.JSON序列化 string JsonStr= JsonConvert.SerializeO ...
- Net中JSON序列化和反序列化处理(日期时间特殊处理)
0 缘由 笔者最近在web api端使用Json.Net进行序列化处理,而在调用端使用DataContractSerializer进行反序列化,遇到日期时间处理反序列化不成功[备注:笔者使用Net ...
- Newtonsoft.Json 序列化和反序列化 时间格式 [转]
1.JSON序列化 string JsonStr= JsonConvert.SerializeObject(Entity); eg: A a=new A(); a.Name="Elain ...
随机推荐
- Java Selenide 介绍&使用
目录 Selenide 介绍 官方快速入门 元素定位 元素操作 浏览器操作 断言 常用配置 Selenide 和 Webdriver 对比 Selenide 介绍 Selenide github Se ...
- Python SQL execute加参数的原理
在Python中,当用pymysql库,或者MySQLdb库进行数据库查询时,为了防止sql注入,可以在execute的时候,把参数单独带进去,例如: def execute_v1(): config ...
- JUC之文章整理以及汇总
JUC文章汇总 JUC部分将学习<JUC并发编程的艺术>和<尚硅谷-大厂必备技术之JUC并发编程>进行博客的整理,各文章中也会不断的完善和丰富. JUC概述 JUC的视频学习和 ...
- gin框架中的渲染
各种数据格式的响应 json.结构体.XML.YAML类似于java的properties.ProtoBuf 点击查看代码 // json响应 func someJson(context *gin.C ...
- .NET SourceGenerators 根据 HTTPAPI 接口自动生成实现类
目录 摘要 元数据分析 使用 Source generators 实现 使用 Source generators 实现程序集分析 使用方法 SourceCode && Nuget pa ...
- 首页页面(html+css+js)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- electron-vue 项目添加启动loading动画问题
前言 electron-vue脚手架搭建的项目,在开发阶段可能你注意不到项目启动慢的问题,但是在build 生成的exe可执行文件,启动后,要反应很久才能进入到app.vue 中加载的页面,体验性很差 ...
- Python数据结构之“栈”与“队列”
栈(Stacks): ·定义:是一种只能通过访问其一端来实现的数据存储于检索的线性数据结构,具有后进先出(last in first out,LIFO)的特征 ·主要操作: 1. Stack():建立 ...
- React凤凰项目规范
技术资源 基础语法 ES6 TS 框架 React Redux React-redux React-Router UmiJS Dva 组件库 AntDesign AntV 构建编译 Webpack b ...
- java中静态代码块详解
感谢大佬:https://blog.csdn.net/qq_35868412/article/details/89360250 今天在项目中看到这行代码,静态代码块,很久没用静态代码块了,今天来复习一 ...