一 序列化、反序列化
https://www.liaoxuefeng.com/wiki/897692888725344/923056033756832
序列化、反序列化:
序列化:pickling,将内存中变量(python对象)转为可存储或可传输数据类型的过程;
反序列化:unpickling,将存储或传输接收到的数据类型转为python对象的过程。
序列化、反序列化模块: cPickle、pickle
前者C语言写的,快;后者纯python写的,慢;优先用前者,导入失败再后者。
序列化函数:dump()、dumps()
cPickle.dump():将对象序列化并写入file-like object,dump(object,file-like)
cPickle.dumps():将对象序列化为String并返回
反序列化函数: load()、loads()
cPickle.load():从file-like object中反序列化得到对象,dump(file-like)
cPickle.loads():从String中反序列化得到对象
补充:file-like object
https://www.jianshu.com/p/4dfe8692f224
https://blog.csdn.net/weixin_41767339/article/details/90733043
Python中有read()方法的对象统称为file-like Object(类文件对象),如:open()函数返回的TextIOWrapper对象(open返回的不是String),TextIOWrapper的read()方法返回的是String。
二 json序列化、反序列化
https://www.liaoxuefeng.com/wiki/897692888725344/923056033756832
json序列化、反序列化
json模块可以实现python对象到json格式的转换,按自定义规则进行序列化、反序列化。
序列化函数: python转为json格式,dump()、dumps()
json.dump(obj)
json.dumps(obj)
反序列化函数: json转为python对象,load()、loads()【区别同cPickle模块】
json.load(file-like)
json.loads(str)
自定义类的序列化与反序列化
python内置的dict、list可以直接序列化、反序列化;但自定义类,需要先设置序列化、反序列化的规则。
自定义类序列化: 先将自定义类转为dict,再由dict序列化为json格式
1.创建转换函数
法一:将自定义类的属性作为dict的元素进行转换,一个转换函数对应一个自定义类;
法二:使用类的__dict__属性(直接返回dict),一个转换函数可对应任意自定义类;
注意:这里自定义类都是实体类,类似javabean;
2.dump()中指定转换函数
dump()中可选参数default用于指定转换函数
dump(obj,default=student2dict) # 对于自定义的转换函数
dump(obj,default=lambda obj:obj.__dict__) # 对于使用类的__dict__属性,使用lambda表达式
注意:
dunmp(ident=XXX)参数可以美化输出,其中ident值换行后句首空格数;不管设置多少都会换行美化输出;
自定义类反序列化: 先将json格式转为dict,再由dict转为自定义类
1.创建转换函数
根据dict的元素生成对象
2.load()中指定转换:
load的()中可选参数object_hook用于指定转换函数
load(file-like,object_hook=dict2student)
注意: json有多层嵌套时,使用object-hook会报错,还是手动用load()转为dict,然后由dict创建自定义类对象
注意:
上面dumps、loads的使用很大程度上基于以下两点:无论多复杂的对象都可以通过__dict__转为字典,无论多复杂的字符串都可以通过json.load()转为字典;这两点其实已经解决了核心问题,后一条在爬虫中起大作用;
三 json配置文件
json作为配置文件时,使用过程中发现一些细节问题:
1.反序列化时,json中的字典转为自定义对象还是Dict对象?
python的对象和字典在json文件中都是字典格式,在反序列化时要看json中这部分数据在代码中对应哪种。那么,代码中想使用配置信息时,是以字典的方式使用还是以对象的方式使用?以对象方式使用的好处在于,编辑器可以提示属性名,通过访问属性的方式访问数据。缺点是反序列化更麻烦。
如下所示:第一种情况直接用Dict表示更好,第二种中Person类表示更好。
# 数据是并列的关系
{
"数学":100,
"语文":100,
"英语":100
}
# 数据是一个实体的属性
{
"姓名":"张三",
"性别":"男",
"年龄":15
}
2.用dict存储信息时,若字典的key就是名字,value中还要不要再加一个name字段?
{
"abc":{
"id":123,
...
}
...
}
{
"abc":{
"name":abc, # 这个字段要不要设置?
"id":1233
...
}
...
}
value中要这个字段,因为json反序列化为dict时,json中字典的键信息与dict无关,这样再从dict转为自定义对象时,自定义对象的name字段信息就没了。
3.list包dict、dict包dict哪种方式存储信息更方便?
[
{
"name":"a",
...
},
{
"name":"b"
...
}
]
{
"a":{
"name":abc
...
},
"a":{
"name":abc
...
}
}
当要遍历所有信息时第一种列表方式更好,当要查找某个信息时第二种方式更好。