侵权投诉

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

马哥Linux运维 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

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

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

收藏 人收藏
分享:

评论

相关推荐

如何去实现STM23F4的FLASH读取
STM32F4XX的闪存擦除方式分为哪几种? 如何去实现STM23F4的FLASH读取? ...
发表于 10-18 15:06 0次 阅读
怎样使用STM32CubeMx生成FMC的初始化代码呢
W9825G6KH-6的原理是怎样的? 怎样使用STM32CubeMx生成FMC的初始化代码呢? ...
发表于 10-18 09:52 0次 阅读
怎样在音频播放系统里面进行音频系数量化的设计呢
怎样在音频播放系统里面进行音频系数量化的设计呢?要注意什么问题吗?...
发表于 10-18 09:27 0次 阅读
怎样去编写STM32F407+ESP8266的开发代码
怎样去编写STM32F407+ESP8266的开发代码? STM32F407+ESP8266的硬件是怎样进行连接的? ...
发表于 10-18 09:17 0次 阅读
怎样去使用GOTO语句呢
什么是goto语句?为什么goto语句这么不受待见呢?...
发表于 10-18 08:35 0次 阅读
怎样将stm32rct6的串口例程移植到stm32f103c8t6上去呢
怎样将stm32rct6的串口例程移植到stm32f103c8t6上去呢?有哪些操作步骤?...
发表于 10-18 07:53 0次 阅读
一种基于51单片机的流水灯实验
怎样去编写基于51单片机的流水灯实验代码?
发表于 10-18 07:19 0次 阅读
怎样去开发一种基于STM32的贪吃蛇小游戏
怎样去开发一种基于STM32的贪吃蛇小游戏?
发表于 10-18 06:42 0次 阅读
关于Python18个你不知道的高效编程技巧
初识Python语言,觉得python满足了我上学时候对编程语言的所有要求。python语言的高效编....
的头像 马哥Linux运维 发表于 10-15 11:23 187次 阅读
PCB的设计、打板和焊接
最近MicroPython在嵌入式系统领域受到大家的喜爱,攻城狮们都纷纷研究起来,就连我们Funpa....
的头像 电子森林 发表于 10-15 10:04 151次 阅读
能快速找到代码运行最慢部分的编程神器
天下武功,唯快不破。 编程也不例外,你的代码跑的快,你能快速找出代码慢的原因,你的码功就高。 今天分....
的头像 Linux爱好者 发表于 10-13 16:40 110次 阅读
动态内存分配的注意事项及本质是什么
C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态....
的头像 C语言编程学习基地 发表于 10-13 15:37 226次 阅读
动态内存分配的注意事项及本质是什么
ACL2021的跨视觉语言模态论文之跨视觉语言模态任务与方法
来自:复旦DISC 引言 本次分享我们将介绍三篇来自ACL2021的跨视觉语言模态的论文。这三篇文章....
的头像 深度学习自然语言处理 发表于 10-13 10:48 197次 阅读
ACL2021的跨视觉语言模态论文之跨视觉语言模态任务与方法
一文详解虚函数及其相关知识点
本期是C++基础语法分享的第七节,今天给大家来分享一下: (1)虚析构函数; (2)纯虚函数; (3....
的头像 C语言编程学习基地 发表于 10-13 10:14 191次 阅读
用Python实现3D地图教程
前言 本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题....
的头像 马哥Linux运维 发表于 10-13 10:09 158次 阅读
用Python实现3D地图教程
关于Python对交通路口的红绿灯进行颜色检测
转自 |   Python联盟 1.视频读取 首先把视频读取进来,因为我测试的视频是4k的所以我用r....
的头像 新机器视觉 发表于 10-13 09:32 223次 阅读
关于Python对交通路口的红绿灯进行颜色检测
spring中声明式事务实现原理猜想
  @Transactional注解简介 @Transactional 是spring中声明式事务管....
的头像 Android编程精选 发表于 10-13 09:20 184次 阅读
xv6的文件系统是如何实现的
文件系统 本文继续来看 的文件系统部分, 将文件系统的设计分为 7 层: ,磁盘、缓存区、日志三个部....
的头像 Linux阅码场 发表于 10-12 18:00 129次 阅读
 xv6的文件系统是如何实现的
Linux中匿名页的访问分析
Linux 中 有后备文件支持的页称为文件页,如属于进程的代码段、数据段的页,内存回收的时候这些页面....
的头像 Linux阅码场 发表于 10-12 17:52 153次 阅读
处理器中异常和中断解决
异常是能够引起程序流偏离正常流程的事件,当异常发生时,正在执行的程序就会被挂起,处理器转而执行一块与....
的头像 单片机匠人 发表于 10-12 17:14 272次 阅读
如何制作数据可视化大屏
经常有小伙伴问,如何制作数据可视化大屏? 今天将手把手带你爬取奥运会相关信息,并利用 可视化大屏 为....
的头像 Linux爱好者 发表于 10-12 16:31 140次 阅读
如何制作数据可视化大屏
RUST的真实驱动案例
我们无法确定RUST在内核的最终趋势,有多少人愿意迁移,但是至少Linus愿意试水。 Wedson ....
的头像 Linux阅码场 发表于 10-12 15:59 85次 阅读
RUST的真实驱动案例
那些有着巨大影响力的代码盘点
2009 年,Facebook 推出了一份改变世界的代码——点「赞」按钮。「赞」是包括 Leah P....
的头像 strongerHuang 发表于 10-12 15:46 176次 阅读
那些有着巨大影响力的代码盘点
那些书本上都没有提到的C语言volatile用法
许多程序员都无法正确理解C语言关键字volatile,这并不奇怪。因为大多数C语言书籍通常都是一两句....
的头像 STM32嵌入式开发 发表于 10-12 14:47 913次 阅读
那些书本上都没有提到的C语言volatile用法
什么是MicroPython 它能做什么有什么局限
随着Python成为主流的编程语言,MicroPython在嵌入式系统领域也越来越热门起来,尤其是大....
的头像 电子森林 发表于 10-12 11:44 218次 阅读
PO VO DTO转换神器的思路
当然有的人喜欢写get set,或者用BeanUtils 进行复制,代码只是工具,本文只是提供一种思....
的头像 Linux爱好者 发表于 10-12 11:13 195次 阅读
传统关系型数据库和ES的差别
https://juejin.cn/post/6889020742366920712 本文不会关注 ....
的头像 Android编程精选 发表于 10-12 10:49 123次 阅读
10具有挑战性的Python项目创意
你知道 Python 是被称为 全能编程语言 的吗?是的,它确实是,虽然不应该在每个项目中都使用它。....
的头像 Android编程精选 发表于 10-12 10:43 248次 阅读
如何把Python和Excel两大数据工具进行集成
  这次我们会介绍如何使用xlwings将Python和Excel两大数据工具进行集成,更便捷地处理....
的头像 数据分析与开发 发表于 10-12 09:41 147次 阅读
如何把Python和Excel两大数据工具进行集成
如何在Colab中使用SQL
如今,编码测试在数据科学面试过程中几乎是标准的。 作为一名数据科学招聘经理,我发现一个20-30分钟....
的头像 智能感知与物联网技术研究所 发表于 10-12 09:39 164次 阅读
如何在Colab中使用SQL
Python开发中Pycharm的实用小技巧
  Pycharm作为Python开发最常用的IDE之一,不仅兼容性好,而且功能也相当丰富,比如调试....
的头像 马哥Linux运维 发表于 10-12 09:36 136次 阅读
命令行工具Kubectl的别样用法
  kubectl 是 K8s 官方附带的命令行工具,可以方便的操作 K8s 集群。这篇文章主要介绍....
的头像 马哥Linux运维 发表于 10-12 09:31 126次 阅读
Python的时间处理模块中处理日期与时间的全面总结
Python的时间处理模块在日常的使用中用的较多,但是使用的时候基本上都是要查资料,还是有些麻烦的,....
的头像 马哥Linux运维 发表于 10-12 09:24 182次 阅读
Python的时间处理模块中处理日期与时间的全面总结
C语言中驱动法编程的代码案例
数据压倒一切。如果选择了正确的数据结构并把一切组织的井井有条,正确的算法就不言自明。编程的核心是数据....
的头像 硬件攻城狮 发表于 10-12 09:21 175次 阅读
Python中最常用的几种线程锁你会用吗
前言本文将继续围绕 threading 模块讲解,基本上是纯理论偏多。 对于日常开发者来讲很少会使用....
的头像 马哥Linux运维 发表于 10-11 16:07 149次 阅读
一本教你怎么写出让同事无法维护的代码
‍对,你没看错,本文就是教你怎么写出让同事无法维护的代码。一、程序命名 容易输入的变量名 。比如:F....
的头像 Linux爱好者 发表于 10-11 15:45 171次 阅读
优秀的 Verilog/FPGA开源项目介绍(一)
优秀的 Verilog/FPGA开源项目介绍(一)-PCIe通信 今天开始会陆续介绍一些优秀的开源项....
的头像 OpenFPGA 发表于 10-11 15:31 245次 阅读
优秀的 Verilog/FPGA开源项目介绍(一)
探究关于数字电路的一些基础知识
1.常用门电路图 2.逻辑代数的基本定理----化简时比较好用 反演定理:对于任意一个逻辑式 Y,若....
的头像 FPGA设计论坛 发表于 10-11 15:04 228次 阅读
探究关于数字电路的一些基础知识
鸿蒙的网络管理功能你们知道有多厉害吗
  本示例演示了如何使用网络管理模块相关接口,演示了以下功能: 功能 1: 使用默认网络,打开连接,....
的头像 HarmonyOS技术社区 发表于 10-11 14:26 263次 阅读
鸿蒙的网络管理功能你们知道有多厉害吗
开发一个鸿蒙版仿苹果计算器教程.附代码
众所周知鸿蒙 JS 框架是非常轻量级的 MVVM 模式。通过使用和 Vue2 相似的属性劫持技术实现....
的头像 HarmonyOS技术社区 发表于 10-11 14:17 225次 阅读
开发一个鸿蒙版仿苹果计算器教程.附代码
鸿蒙开发中怎么引入第三方库
Android 发展到现在不仅提供了很多 API,还提供了很多第三方库。这降低了我们开发者的开发难度....
的头像 HarmonyOS技术社区 发表于 10-11 14:11 200次 阅读
Linux内核热补丁安全隐患的探索
Linux 内核热补丁可以修复正在运行的 linux 内核,是一种维持线上稳定性不可缺少的措施,现在....
的头像 Linux阅码场 发表于 10-11 11:54 195次 阅读
Linux内核热补丁安全隐患的探索
SystemVerilog语言介绍汇总
作者:limanjihe  https://blog.csdn.net/limanjihe/arti....
的头像 FPGA之家 发表于 10-11 10:35 207次 阅读
剖析verilog2005的骚操作之对数函数
小技巧分享: verilog下取对数其实可用$clog2这个系统函数,和自己找代码里面写入funct....
的头像 玩儿转FPGA 发表于 10-09 15:29 198次 阅读
剖析verilog2005的骚操作之对数函数
Floyd如何求图的最短路径
前言 在 图论 中,在寻路最短路径中除了 Dijkstra 算法以外,还有 Floyd 算法也是非常....
的头像 算法与数据结构 发表于 10-09 14:38 133次 阅读
Floyd如何求图的最短路径