首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Serialization and Deserialization

Serialization and Deserialization

作者头像
Cloud-Cloudys
发布2020-07-07 16:29:20
5580
发布2020-07-07 16:29:20
举报

序列化与反序列化

Serialization:Data Structure/Object –> Binary String Deserialization:Binary String –> Data Structure/Object Goals:Cross-platform Communication、Persistent Storage and More

Python中对象的序列化与反序列化

pickle module

pickle 仅可用于 Python,pickle所使用的数据流格式仅可用于 Python pickle 模块可以将复杂对象转换为字节流,也可以将字节流转换为具有相同内部结构的对象。 可被pickling和unpickling的对象:https://docs.python.org/zh-cn/3/library/pickle.html#what-can-be-pickled-and-unpickled

pickle提供了优秀的方法方便我们对对象进行pickling(封存)和unpickling(解封)

使用dumps和loads方法进行序列化和反序列化

>>> import pickle
>>> person = dict(name='shan', age=20, sex="man")
>>> pickle.dumps(person)  # dumps方法会将obj序列化为bytes返回
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00shanq\x02X\x03\x00\x00\x00ageq\x03K\x14X\x03\x00\x00\x00sexq\x04X\x03\x00\x00\x00manq\x05u.
>>>
>>> with open("dump.txt","wb") as f:
...     pickle.dump(person, f)
...
>>> f = open("dump.txt","rb")
>>> d = pickle.load(f)
>>> f.close()
>>> d
{'name': 'shan', 'age': 20, 'sex': 'man'}
>>> pickle.loads(pickle.dumps(d))
{'name': 'shan', 'age': 20, 'sex': 'man'}

json module

相比于pickle,json只能表示内置类型的子集,不能表示自定义的类 json格式的文件的易读性更好 Python json模块提供的API与pickle模块很相似

使用dumps和loads进行序列化和反序列化

>>> import json
>>> person = dict(name='shan', age=20, sex="man")
>>> json.dumps(person)
'{"name": "shan", "age": 20, "sex": "man"}'
>>>
>>> json_str = json.dumps(person)
>>> json.loads(json_str)
{'name': 'shan', 'age': 20, 'sex': 'man'}
  • dumps方法会将obj转换为标准格式的JSON str并返回
  • loads方法可将包含JSON文档的str、bytes或者bytearray反序列化为Python对象

自定义对象的序列化与反序列化

对于自定义对象的序列化和反序列化操作需要我们实现专门的encoder和decoder 需要用到dumps方法的default参数和loads方法的object_hook参数 https://docs.python.org/3/library/json.html#json.loads https://docs.python.org/3/library/json.html#json.loads

>>> import json
>>>
>>> class Student(object):
...     def __init__(self, name, age, score):
...         self.name = name
...         self.age = age
...         self.score = score
...
>>> def student2dict(std):
...     return {
...         'name': std.name,
...         'age': std.age,
...         'score': std.score
...     }
...
>>> def dict2student(d):
...     return Student(d['name'], d['age'], d['score'])
...
>>> s = Student('Bob', 20, 88)
>>> print(json.dumps(s, default=student2dict))
{"name": "Bob", "age": 20, "score": 88}
>>> json_str = json.dumps(s, default=student2dict)
>>> print(json.loads(json_str, object_hook=dict2student))
<__main__.Student object at 0x000001B101675198>
>>> json.loads(json_str, object_hook=dict2student)
<__main__.Student object at 0x000001B101675128>
>>> old = json.loads(json_str, object_hook=dict2student)
>>> old.name
'Bob'

third-party module:marshmallow

marshmallow is an ORM/ODM/framework-agnostic library for converting complex datatypes, such as objects, to and from native Python datatypes.

>>> import datetime as dt
>>> import marshmallow
>>> from dataclasses import dataclass
>>>
>>> from marshmallow import Schema, fields
>>>
>>> @dataclass
... class Album:
...     title: str
...     release_date: dt.date
...
>>> class AlbumSchema(Schema):
...     title = fields.Str()
...     release_date = fields.Date()
...
>>> album = Album("Seven Innovation Base", dt.date(2019, 11, 23))
>>> schema = AlbumSchema()
>>> data = schema.dump(album)  # obj -> dict
>>> data
{'title': 'Seven Innovation Base', 'release_date': '2019-11-23'}
>>> data_str = schema.dumps(album)  # obj -> str
>>> data_str
'{"title": "Seven Innovation Base", "release_date": "2019-11-23"}'
  • 使用 marshmallow 可以很方便的对自定义对象进行序列化和反序列化
  • 对object进行在序列化之前,需要为object创建一个schema,schema中的字段名必须与自定义的object中的成员一致
  • dumps method:obj -> str, dump method:obj -> dict
  • 反序列化的 dict -> obj 需要使用decorator:post_load自己实现
from marshmallow import Schema, fields, post_load

class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email

    def __repr__(self):
        return "<User(name={self.name!r})>".format(self=self)

class UserSchema(Schema):
    name = fields.Str()
    email = fields.Email()

    @post_load
    def make_user(self, data, **kwargs):
        return User(**data)

user_data = {
    "email": "ken@yahoo.com",
    "name": "Ken",
}
schema = UserSchema()
result = schema.load(user_data)
print(result)  # 输出结果:<User(name='Ken')>

References

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年11月25日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 序列化与反序列化
  • Python中对象的序列化与反序列化
    • pickle module
      • 使用dumps和loads方法进行序列化和反序列化
    • json module
      • 使用dumps和loads进行序列化和反序列化
      • 自定义对象的序列化与反序列化
    • third-party module:marshmallow
    • References
    相关产品与服务
    文件存储
    文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档