在我的应用中,序列化就是把类转成符合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序列化和反序列化的更多相关文章

  1. python处理JSON 序列化与反序列化

    #序列化 >>> import json>>> d={"key":"value"}>>> d{'key': ...

  2. 【Python】Json序列化和反序列化模块dumps、loads、dump、load函数介绍

    1.json.dumps()  json.dumps()用于将dict类型的数据转成str,因为如果直接将dict类型的数据写入json文件中会发生报错,因此在将数据写入时需要用到该函数. 转换案例: ...

  3. python json序列化与反序列化操作

    python json序列化与反序列化操作 # dumps() dict-->str 序列化 # loads() str---dict 反序列化 result1 = json.dumps({'a ...

  4. python 3 json 序列化

    python 3 json 序列化 我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特 ...

  5. DotNet的JSON序列化与反序列化

    JSON(JavaScript Object Notation)JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式.在现在的通信中,较多的采用JSON数据格式,JSON有 ...

  6. C#中JSON序列化和反序列化

    有一段时间没有到博客园写技术博客了,不过每天逛逛博客园中大牛的博客还是有的,学无止境…… 最近在写些调用他人接口的程序,用到了大量的JSON.XML序列化和反序列化,今天就来总结下json的序列化和反 ...

  7. Newtonsoft.Json 序列化和反序列化 时间格式

    From : http://www.cnblogs.com/litian/p/3870975.html 1.JSON序列化 string JsonStr= JsonConvert.SerializeO ...

  8. Net中JSON序列化和反序列化处理(日期时间特殊处理)

    0  缘由 笔者最近在web api端使用Json.Net进行序列化处理,而在调用端使用DataContractSerializer进行反序列化,遇到日期时间处理反序列化不成功[备注:笔者使用Net ...

  9. Newtonsoft.Json 序列化和反序列化 时间格式 [转]

    1.JSON序列化 string JsonStr= JsonConvert.SerializeObject(Entity); eg:   A a=new A(); a.Name="Elain ...

随机推荐

  1. Go 变量及基本数据类型3

    #### Go 变量及基本数据类型(三)今天学习一下剩下的两个基本数据类型(布尔类型,字符串类型)以及基本数据类型的相互转换##### 布尔类型布尔类型也称为bool 类型, bool 类型只允许取值 ...

  2. java内部类概述和修饰符

    1 package face_09; 2 /* 3 * 内部类访问特点: 4 * 1,内部类可以直接访问外部类的成员. 5 * 2,外部类要访问内部类,必须建立内部类的对象. 6 * 7 * 一把用于 ...

  3. JDBC固定步骤-java连接MySQL

    static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver"; static final String DB_URL = ...

  4. Java当中“+=”和“=+”的区别

    "+="会自动类型强制转换! 隐含了一个强制类型转换! 一 string a1 = "9"; int a2 = 10; a1+=a2; a1=a1+a2; 不会 ...

  5. RocketMq如何顺序消费的消息offest

    RocketMq对于消费者对于消息的如何处理的 1:如果设置了自动提交 返回: ConsumeOrderlyStatus.COMMIT, ConsumeOrderlyStatus.ROLLBACK, ...

  6. Transformer可解释性:注意力机制注意到了什么?

    原创作者 | FLPPED 论文: Self-Attention Attribution: Interpreting Information Interactions Inside Transform ...

  7. 分布式系统及CAP理论

    一.集中式系统 在学习分布式之前,先了解一下与之相对应的集中式系统是什么样的. 集中式系统用一句话概括就是:一个主机带多个终端.终端没有数据处理能力,仅负责数据的录入和输出.而运算.存储等全部在主机上 ...

  8. 入门-k8s查看Pods/Nodes (四)

    目标 了解Kubernetes Pods(容器组) 了解Kubernetes Nodes(节点) 排查故障 Kubernetes Pods 在 部署第一个应用程序 中创建 Deployment 后,k ...

  9. Mac版jdk1.6

    java sdk 1.6 for mac 在苹果官网下载 https://support.apple.com/kb/DL1572?locale=zh_CN

  10. xshell脚本之条件语句

    xshell脚本之条件语句 1.test命令: 如果test命令中列出的条件成立,test命令就会退出并返回状态码0, 如果条件不成立,test命令就会退出并返回非零的退出状态码,这使得if-then ...