0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

分享一个最新的的Python对象序列化方式

马哥Linux运维 ? 来源:Hynek Schlawack ? 作者:Hynek Schlawack ? 2021-09-01 15:19 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

许多Python标准库都有一些未被赏识的精华。其中之一是允许简单优雅的基于参数类型的函数分发。这一特性对于任意对象的序列化而言是非常完美的——例如对于web API的JSON或结构化日志而言。

谁应该都见过这个:

9b2e5f14-0acf-11ec-911a-12bb97331649.png

虽然这不是什么大问题。json模块(API继承自simplejson)提供了两种方式来序列化对象:

1. 实现一个default()函数,它接收一个对象作为参数并且返回可以被JSONEncoder理解的东西;

2. 你自己实现或子类化一个JSONEncoder,并且把它作为cls传递给dump方法。你可以自己实现它或者简单地重写JSONEncoder.default()方法。

由于一些第三方的实现希望能够被大多数程序兼容,所以他们都不同程度的模仿了json模块的API1。

扩展性

所有上述方法的共性是它们不具有扩展性:不提供对新类型的支持。你的default()函数需要知道所有你想要序列化的自定义类型。这意味着你或者像这样写你的函数:

9b3d44ac-0acf-11ec-911a-12bb97331649.jpg

这看起来非常痛苦,因为你需要在一个地方为所有不同类型对象增加序列化结果2。

或者另一种方法,你可以自己尝试提出一种一般性的解决方案,就像Pyramid的JSON渲染器在JSON.add_adapter中做的一样,它使用了被广泛低估的zope.interface的适配器注册表3。

另一方面,Django自己实现了一个DjangoJSONEncoder,它是json.JSONEncoder的子类,它知道如何去编码日期,时间,UUID和premise等。但是除此之外,你又需要依靠自己了。如果你想深入研究Django和web API,那么你可能已经准备好使用Django的REST框架了。它们实现了一整套序列化系统,它比仅仅让数据进行json.dump()做了更多的工作。

最后,为了完整性,我感觉我不得不提到我自己在我第一天开始就极其讨厌的structlog中的解决方案:为你的类增加一个__structlog__方法,它会像__str__一样返回一个序列化后的表示方法。请不要重复我的错误。标签:software clown。

JSON已经很流行了,然而很奇怪的是我们对于序列化的解决方案却仍旧不够完善。我个人想要的是能够注册一个中心化的序列化工具,但是却以一个去中心化的方式来使用,这样可以不需要对我的类(或者更糟的,第三方类)进行任何修改。

进入PEP443

Python3.4以PEP 443的形式给出了对这个问题的一个好的解决方案:functools.singledispatch(老式Python版本也可以在PyPI上找到)。

简单说,你可以定义一个默认的函数然后根据第一个参数的类型注册一个该函数的额外版本:

9b57351a-0acf-11ec-911a-12bb97331649.jpg

现在你也可以对datetime实例调用to_serializable()方法,singledispatch会选择正确的函数

9b634044-0acf-11ec-911a-12bb97331649.png

这一方法让你能够把你的序列化器放在任何你想放的位置:放在类里,在一个独立的模块里,或者放在JSON相关的代码里。你自己选!但是你的类要保持干净,并且你不需要巨大的繁琐的if-elif-else分支。

更深入一点

显然,@singledispatch的使用比JSON更加深入。一般而言,为不同类型的对象绑定不同的行为以及独立的序列化方式是普遍适用的4。我的一些校对员提到了他们尝试了采用字典类近似替代可调用对象以及其他一些类似的“残暴的”做法。

换句话说,@singledispatch就是一个长久以来就存在的但是却被你忽略的函数。

P.S. 当然,PyPI中也有一个*multiple*dispatch。

脚注

1. 然而,对于非常出名的一个:UltraJSON一点都不支持自定义对象的序列化,此外,python-rapidjson仅仅支持default()函数。

2. 利用attrs是可以很好管理的!也许你应当使用attrs!

3. 不幸的是Pyramid使用的API自从zope.component移植过来之后还没有形成文档。

4. 我听说将singlepatch加进标准库的最原始动力来自于对pprint的一个更优雅的实现(虽然从来没有实现过)

原文链接:https://hynek.me/articles/serialization/

(版权归原作者所有,侵删)

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • API
    API
    +关注

    关注

    2

    文章

    1665

    浏览量

    64248
  • 函数
    +关注

    关注

    3

    文章

    4385

    浏览量

    65155
  • 代码
    +关注

    关注

    30

    文章

    4906

    浏览量

    71033
  • python
    +关注

    关注

    56

    文章

    4831

    浏览量

    87460
  • JSON
    +关注

    关注

    0

    文章

    122

    浏览量

    7435

原文标题:更好的Python对象序列化方式

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基础篇3:掌握Python中的条件语句与循环

    : print(\"你还很小。\") 循环 循环允许程序重复执行段代码,直到满足某个条件为止。Python中有几种不同的循环结构。 for循环 for循环通常用于遍历序列(如列表、元组
    发表于 07-03 16:13

    TaskPool和Worker的对比分析

    TaskPoolWorker内存模型线程间隔离,内存不共享。线程间隔离,内存不共享。 参数传递机制采用标准的结构克隆算法(Structured Clone)进行序列化、反序列化,完成参数传递。 支持ArrayBuffer
    发表于 06-18 06:43

    鸿蒙5开发宝藏案例分享---跨线程性能优化指南

    发现鸿蒙宝藏:跨线程序列化性能优化实战指南 大家好呀!今天在翻鸿蒙文档时挖到超级实用的工具—— DevEco Profiler的序列化检测功能 !平时用<span class
    发表于 06-12 17:13

    快手上线鸿蒙应用高性能解决方案:数据反序列化性能提升90%

    普通对象(如 JSON 数据)与类实例进行互转,是实现面向对象编程与数据序列化解耦的核心工具。随着业务复杂度的提升,该库在反序列化过程中逐渐暴露出性能瓶颈,影响用户核心体验。因此
    发表于 05-15 10:01

    spartan 6 14位LVDS 反序列化

    spartan 6系列的FPGA 与14位ADC 输出LVDS信号 怎么实现1:14的串转并呢?iserdes2 在ise里面最高只能实现8位啊
    发表于 04-25 15:20

    什么是SerDes?SerDes有哪些应用?

    SerDes是种功能块,用于对高速芯片间通信中使用的数字数据进行序列化和反序列化。用于高性能计算(HPC)、人工智能(AI)、汽车、移动和物联网(IoT)应用的现代片上系统(SoC
    的头像 发表于 03-27 16:18 ?2583次阅读
    什么是SerDes?SerDes有哪些应用?

    使用Yolo-v3-TF运行OpenVINO?对象检测Python演示时的结果不准确的原因?

    的模型与对象检测 Python* Demo 配合使用时无法检测对象python3 open_model_zoo/demos/object_detection_demo/
    发表于 03-06 06:31

    无法在Windows Subsystem for Linux 2上使用对象检测Python演示运行YoloV4模型?

    在 WSL2 上运行对象检测 python 演示。 使用 CPU 运行 object_detection_demo.py 时遇到错误: OpenCV: FFMPEG: tag
    发表于 03-05 08:43

    DLP3010序列中包含8bit图和1bit图投影错误怎么解决?

    DLP3010投影仪投影两图形序列。第一个序列包含18bit的pattern set,和
    发表于 02-21 10:15

    对象存储是什么结构类型?

    对象存储属于非结构数据存储架构,采用扁平命名空间结构。其核心通过唯标识符(ObjectID)定位数据对象,突破传统文件系统的层级目录限
    的头像 发表于 02-10 11:14 ?360次阅读

    如何使用Python构建LSTM神经网络模型

    构建LSTM(长短期记忆)神经网络模型是涉及多个步骤的过程。以下是使用Python和Keras库构建LSTM模型的指南。 1. 安装
    的头像 发表于 11-13 10:10 ?1651次阅读

    【每天学点AI】例子带你了解Python装饰器到底在干嘛!

    进行“加料”呢?Python装饰器提供了更为优雅的方式来增强现有函数的行为,并且不需要修改现有的函数代码及调用方式。接下来通过
    的头像 发表于 09-20 16:54 ?819次阅读
    【每天学点AI】<b class='flag-5'>一</b><b class='flag-5'>个</b>例子带你了解<b class='flag-5'>Python</b>装饰器到底在干嘛!

    【「时间序列与机器学习」阅读体验】时间序列的信息提取

    本章主讲时间序列的信息提取,章节中有许多概念定义和数学公式,并配有Python代码演示,细细品读与理解动手演练,还是很开拓思维视野的。下面以笔记形式进行展开。 时间序列的信息提取是时间序列
    发表于 08-17 21:12

    【《时间序列与机器学习》阅读体验】+ 时间序列的信息提取

    、特征的范数归一化。每个定义和命题都给出了证明过程和示例,示例还提供了Python代码,方便学习。 以下是特征的最小最大缩放的示例数据和代码: 由于我的本子有Python运行环境,编辑
    发表于 08-14 18:00

    【「时间序列与机器学习」阅读体验】全书概览与时间序列概述

    他领域(如自然语言处理、计算机视觉等)的关联。 ●第2章“时间序列的信息提取”:介绍特征工程的核心概念及其在时间序列分析中的广用,比如对原始数据进行归一化、缺失值填充等转换;以及如何通过特征工程从时间
    发表于 08-07 23:03