Python---数据序列化

转载自如下文章
###序列化和反序列化

序列化:就是把正在运行中的内存数据存储到硬盘文件的过程,内存中正在运行的数据不管是什么数据类型,都必须先转化为__字符串或者二进制数__。
反序列化:就是序列化的逆运算,把存储到硬盘文件的内容,重新加载到内存中。

##pickle模块##

pickle,用于python特有的类型 和 python的数据类型间进行转换,只能在python语言中使用,无法兼容其他语言。
pickle数据是以二进制形式存储的。
pickle模块提供了四个功能:dumps、dump、loads、load.

import pickle
#存储变量
dic = {'age': 23, 'job': 'student'}
byte_data = pickle.dumps(dic)
print(byte_data)
#out-> b'\x80\x03}q\x00(X\x03\x00\x00\x00jobq\x01X\x07\x00\x00\x00studentq\x02X\x03\x00\x00\x00ageq\x03K\x17u.'
#读取数据
obj=pickle.loads(byte_data)
print(obj)
#out-> {'age': 23, 'job': 'student'}

#也可以存在文件中,使得对象持久化。使用的是dump和load函数,注意和上面的区别,少了s。
#由于pickle写入的是二进制数据,所以打开方式需要以wb和rb的模式。
#序列化
with open('seria_pickle.text','wb') as f:
    dic = {'age': 23, 'job': 'student'}
    pickle.dump(dic,f)

#反序列化
with open('seria_pickle.text','rb') as f:
    data=pickle.load(f)
    print(data)
#out-> {'age': 23, 'job': 'student'}
    print(type(data))
#out-> <class 'dict'>

序列化用户自定义类对象

class Person:
    def __init__(self,name,age,job):
        self.name = name
        self.age  = age
        self.job  = job

    def work(self):
        print('%s 正在 %s.' % (self.name,self.job))

# 将实例存储在变量中,当然也能存在文件中
person1 = Person('王思聪',38,'泡妹子')
data1 = pickle.dumps(person1)
print(data1)
#out-> # b'\x80\x03c__main__\nPerson\nq\x00)\x
person2 = pickle.loads(data1)
print(person2)
#out-><__main__.Person object at 0x7f5d6b7f1048>
person2.work()
#out->王思聪 正在 泡妹子.

#将类本身存储在变量中,loads的时候返回类本身,而非它的一个实例
class_Person = pickle.dumps(Person)
Person = pickle.loads(class_Person)
p = Person('马云', 58, '开淘宝')
p.work()
#out->马云 正在 开淘宝.

# 下面这个例子演示的就是将类存储在文件中
#序列化
with open('seria_person.text','wb') as f:
    pickle.dump(person1,f)
#person1对象以字节形式存到文件seria_person.text中

#反序列化
with open('seria_person.text','rb') as f:
    person_f = pickle.load(f)
    print(person_f)
#out-> <__main__.Person object at 0x7f3a83a880b8>
    person_f.work()
#out-> 王思聪 正在 泡妹子.

##json模块##

pickle可以很方便地序列化所有对象。不过json作为更为标准的格式,具有更好的可读性(pickle是二进制数据)和跨平台性,跨语言性。是个不错的选择。

json,用于字符串 和 python数据类型间进行转换。
json只能处理简单的数据类型,比如字典,列表等,不支持复杂数据类型,如类等数据类型。
json模块提供了四个功能:dumps、dump、loads、load

import json

class Person:
    def __init__(self,name,age,job):
        self.name = name
        self.age  = age
        self.job  = job

    def work(self):
        print('%s 正在 %s.' % (self.name,self.job))
person1 = Person('刘强东',40,'泡奶茶')
with open('person_json.text','w',encoding='utf-8') as f:
    json.dump(person1, f) # 报错

Object of type ‘Person’ is not JSON serializable此时dump函数里传一个参default就可以了,这个参数接受一个函数,这个函数可以将对象转换为字典。

添加一个函数返回字典

def person2dict(person):
    return {'name': person.name,
            'age': person.age,
            'job': person.job}
person1 = Person('刘强东',40,'泡奶茶')
with open('person_json.text','w',encoding='utf-8') as f:
#这里注意,是以字符串存储,所以用w,再加上编码类型,不能用wb,wb是以二进制存储,
    json.dump(person1,f,default=person2dict)

这样返回的就是一个字典了,对象实例有个方法可以简化这一过程。直接调用实例的___dict___。例如

print(person1.__dict__)
{'name': '刘强东', 'age': 40, 'job': '泡奶茶'}

同时在读取的时候load出来的是一个字典,再转回对象就可,同样需要一个object_hook参数,该参数接收一个函数,用于将字典转为对象。

def dict2person(dict):
    return Person(dict['name'],dict['age'],dict['job'])

完整函数

import json

class Person:
    def __init__(self,name,age,job):
        self.name = name
        self.age  = age
        self.job  = job

    def work(self):
        print('%s 正在 %s.' % (self.name,self.job))
        
def person2dict(person):
    return {'name':person.name,
            'age':person.age,
            'job':person.job
            
person1 = Person('刘强东',40,'泡奶茶')
with open('person_json.text','w',encoding='utf-8') as f:
#这里注意,是以字符串存储,所以用w,再加上编码类型,不能用wb,wb是以二进制存储,
    json.dump(person1,f,default=person2dict)
    person1.work()
#out->刘强东 正在 泡奶茶.

def dict2person(dict):
    return Person(dict['name'],dict['age'],dict['job'])

with open('person_json.text','r',encoding='utf-8') as f:
    person2 = json.load(f,object_hook=dict2person)
    print(person2)
#out-><__main__.Person object at 0x7f4813145be0>
    person2.work()
#out->刘强东 正在 泡奶茶.

由于可以使用____dict____代替person2dict函数,再使用lambda函数简化。

with open('person_json.text','w',encoding='utf-8') as f:
    json.dump(person1,f,default=lambda obj:obj.__dict__)
    #使用__dict__和lambda匿名函数简化实例化对象方法
    print(person1.__dict__)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值