为什么把这两个放到一起,理由很简单,不过暂时不解释。
一,先看python提供的序列化模块pickle
import pickle
l = ['柯基', '小李', '大华']
lw = pickle.dumps(l) # 把对象转乘字节流 也就是序列化
print(lw)
with open('l.txt', 'wb') as f: #字节流写入文件
f.write(lw)
with open('l.txt', 'rb') as f: #从文件中读取字节流
lr = f.read()
newl = pickle.loads(lr) #把字节流转换成对象
print(newl)
Output:
b'\x80\x03]q\x00(X\x06\x00\x00\x00\xe6\x9f\xaf\xe5\x9f\xbaq\x01X\x06\x00\x00\x00\xe5\xb0\x8f\xe6\x9d\x8eq\x02X\x06\x00\x00\x00\xe5\xa4\xa7\xe5\x8d\x8eq\x03e.'
['柯基', '小李', '大华']
大段代码都是文件操作,因为要保存起来嘛,所以真正的序列化和反序列化非常简单,dumps()和loads()就结束了。
紧接着看一个简化版就好理解了:
import pickle
l = ['柯基', '小李', '大华']
with open('l.txt', 'wb') as f:
pickle.dump(l, f)
with open('l.txt', 'rb') as f: #从文件中读取字节流
newl = pickle.load(f)
print(newl)
Output:
['柯基', '小李', '大华']
就是提供了两个新的函数dump()和load()把写入文件从文件读这个过程也给封装了。
二,JSON--JSON是UTF-8编码,因为要在网络上传输嘛 节约
现在来回答这个问题,很明显,用pickle序列化的东西,只能用pickle去反序列化,实际上你打开保存pickle序列化的文件,里面全是一些乱码,所以上面的数据传输就现在了python系统内部。JSON就是用来解决这个问题的,JSON是JavaScript的对象表示法,但是因为各种优点,就成了网络上传输数据的一种标准格式。所以把对象序列化乘JSON格式,就可以和其他语言进行通信。
python也内置了json模块:
import json
l = ['柯基', '小李', '大华']
print(json.dumps(l)) #把python对象转成json对象
newl = json.loads('["\u67ef\u57fa", "\u5c0f\u674e", "\u5927\u534e"]') #把json对象转成python对象
print(newl)
Output:
["\u67ef\u57fa", "\u5c0f\u674e", "\u5927\u534e"]
['柯基', '小李', '大华']
当然也有dump()和load() 这里不演示了。可以看到python的list就直接被转换成了json的数组[],其余的还有python的dict会被转换成json的对象{}。
题外话:学到这里,我才明白为什么说python简单,容易入门, 其一是因为内置了大量有用的模块,其二是它这个接口设计的,都一样- -,用起来你就很舒服。
三,接下来看看怎么用josn序列化类
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def Person2Dict(p):
return{
'name':p.name,
'age':p.age
}
p = Person('张三',33)
print(json.dumps(p, default=Person2Dict, ensure_ascii=False)) #ensure_ascii=False中文不按ascii编码
Output:
{"name": "张三", "age": 33}
这里dumps()方法多了一个default属性,就是告诉json模块怎么把我的类转换成json对象,可以看到 Person2Dict实际上是把我们自定义的类型转换成了可以序列化的基本类型。然后dumps实际是去序列化这个基本类型去了。
再看反序列化:
def Dict2Person(d):
return Person(d['name'], d['age'])
jsonStr = '{"name": "张三", "age": 33}'
#newP = json.loads(jsonStr)
#newP = Dict2Person(newP)
newP = json.loads(jsonStr, object_hook=Dict2Person)
print(newP.name, newP.age)
Output:
张三 33
可以想想loads()添加object_hook参数之后,就相当于上面注释掉的两句代码,先转成dict,然后再用我们写好的方法去实例化对象。