python序列化和JSON

为什么把这两个放到一起,理由很简单,不过暂时不解释。

一,先看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,然后再用我们写好的方法去实例化对象。

总结一下就是,python不能序列化自定义的类,需要我们去自己写一个函数把自定义的类转换成可以序列化的对象,比如list,dict这类。

猜你喜欢

转载自blog.csdn.net/qq_21294095/article/details/85176038
今日推荐