阅读本文大概需要 6 分钟。

在很多情况下,我们会有把 Python 对象进行序列化或反序列化的需求,比如开发 REST API,比如一些面向对象化的数据加载和保存,都会应用到这个功能。

这里看一个最基本的例子,这里给到一个 User 的 Class 定义,再给到一个 data 数据,像这样:

现在我要把这个 data 快速转成 User 组成的数组,变成这样:

你会怎么来实现?

或者我有了上面的列表内容,想要转成一个 JSON 字符串,变成这样:

你又会怎么操作呢?

另外如果 JSON 数据里面有各种各样的脏数据,你需要在初始化时验证这些字段是否合法,另外 User 这个对象里面 name、age 的数据类型不同,如何针对不同的数据类型进行针对性的类型转换,这个你有更好的实现方案吗?

初步思路

之前我写过一篇文章这可能是 Python 面向对象编程的最佳实践,介绍过 attrs 和 cattrs 这两个库,它们二者的组合可以非常方便地实现对象的序列化和反序列化。

譬如这样:

运行结果:

好,这里我们通过 attrs 和 cattrs 这两个库来实现了单个对象的转换。

首先我们要肯定一下 attrs 这个库,它可以极大地简化 Python 类的定义,同时每个字段可以定义多种数据类型。

但 cattrs 这个库就相对弱一些了,如果把 data 换成数组,用 cattrs 还是不怎么好转换的,另外它的 structure 和 unstructure 在某些情景下容错能力较差,所以对于上面的需求,用这两个库搭配起来并不是一个最优的解决方案。

另外数据的校验也是一个问题,attrs 虽然提供了 validator 的参数,但对于多种类型的数据处理的支持并没有那么强大。

所以,我们想要寻求一个更优的解决方案。

更优雅的方案

这里推荐一个库,叫做 marshmallow,它是专门用来支持 Python 对象和原生数据相互转换的库,如实现 object -> dict,objects -> list, string -> dict, string -> list 等的转换功能,另外它还提供了非常丰富的数据类型转换和校验 API,帮助我们快速实现数据的转换。

要使用 marshmallow 这个库,需要先安装下:

好了之后,我们在之前的基础上定义一个 Schema,如下:

还是之前的数据:

这时候我们只需要调用 Schema 的 load 事件就好了:

输出结果如下:

这样,我们非常轻松地完成了 JSON 到 User List 的转换。

有人说,如果是单个数据怎么办呢,只需要把 load 方法的 many 参数去掉即可:

输出结果:

当然,这仅仅是一个反序列化操作,我们还可以正向进行序列化,以及使用各种各样的验证条件。

下面我们再来看看吧。

更方便的序列化

上面的例子我们实现了序列化操作,输出了 users 为:

有了这个数据,我们也能轻松实现序列化操作。

序列化操作,使用 dump 方法即可

运行结果如下:

由于是 List,所以 dump 方法需要加一个参数 many 为 True。

当然对于单个对象,直接使用 dump 同样是可以的:

运行结果如下:

这样的话,单个、多个对象的序列化也不再是难事。

经过上面的操作,我们完成了 object 到 dict 或 list 的转换,即:

验证

当然,上面的功能其实并不足以让你觉得 marshmallow 有多么了不起,其实就是一个对象到基本数据的转换嘛。但肯定不止这些,marshmallow 还提供了更加强大啊功能,比如说验证,Validation。

比如这里我们将 age 这个字段设置为 hello,它无法被转换成数值类型,所以肯定会报错,样例如下:

这里如果加载报错,我们可以直接拿到 Error 的 messages 和 valid_data 对象,它包含了错误的信息和正确的字段结果,运行结果如下:

因此,比如我们想要开发一个功能,比如用户注册,表单信息就是提交过来的 data,我们只需要过一遍 Validation,就可以轻松得知哪些数据符合要求,哪些不符合要求,接着再进一步进行处理。

当然验证功能肯定不止这一些,我们再来感受一下另一个示例:

比如这里的 validate 字段,我们分别校验了 name、permission、age 三个字段,校验方式各不相同。

如 name 我们要判断其最小值为 1,则使用了 Length 对象。permission 必须要是几个字符串之一,这里又使用了 OneOf 对象,age 又必须是介于某个范围之间,这里就使用了 Range 对象。

下面我们故意传入一些错误的数据,看下运行结果:

可以看到,这里也返回了数据验证的结果,对于不符合条件的字段,一一进行说明。

另外我们也可以自定义验证方法:

通过自定义方法,同样可以实现更灵活的验证,运行结果:

对于上面的例子,还有更优雅的写法:

通过定义方法并用 validates 修饰符,使得代码的书写更加简洁。

必填字段

如果要想定义必填字段,只需要在 fields 里面加入 required 参数并设置为 True 即可,另外我们还可以自定义错误信息,使用 error_messages 即可,例如:

默认字段

对于序列化和反序列化字段,marshmallow 还提供了默认值,而且区分得非常清楚!如 missing 则是在反序列化时自动填充的数据,default 则是在序列化时自动填充的数据。

例如:

这里我们都是定义的空数据,分别进行序列化和反序列化,运行结果如下:

可以看到,在没有真实值的情况下,序列化和反序列化都是用了默认值。

这个真的是解决了我之前在 cattrs 序列化和反序列化时候的痛点啊!

指定属性名

在序列化时,Schema 对象会默认使用和自身定义相同的 fields 属性名,当然也可以自定义,如:

运行结果如下:

反序列化也是一样,例如:

运行结果如下:

嵌套属性

对于嵌套属性,marshmallow 当然也不在话下,这也是让我觉得 marshmallow 非常好用的地方,例如:

这样我们就能充分利用好对象关联外键来方便地实现很多关联功能。

以上介绍的内容基本算在日常的使用中是够用了,当然以上都是一些基本的示例,对于更多功能,可以参考 marchmallow 的官方文档:https://marshmallow.readthedocs.io/en/stable/,强烈推荐大家用起来。

python那么多库怎么学_这个 Python 库有必要好好学学相关推荐

  1. python多大孩子可以学_少儿python教材适合多大的孩子

    python教材在国内市场上运用的是非常广泛的,它能够给孩子带来更好的编程入门效果.少儿python教材适合多大的孩子?孩子接触起来困难吗?python教材适合4岁以上的孩子,它的优点就是通俗易懂,让 ...

  2. python那么多库怎么学_为什么大家都在学习python?原因在这里

    原标题:为什么大家都在学习python?原因在这里 为什么大家都在学习python? python真的是天生丽质难自弃呀,难怪大家都在学python,这就跟所有姑娘都在追求高富帅,所有男生都在渴望白富 ...

  3. python要和什么一起学_跟哥一起学Python(1) - python简介

    01-写在前面 我做了十几年的程序猿,码过代码.带过项目.做过产品经理.做过软件架构师.因为我是做通信设备软件的,面向底层操作系统,所以我的工作主要以C语言为主.Python在我的工作中通常用来写一些 ...

  4. python末位1的位置_用Python黑了整个学院学姐的电话和QQ,爬虫牛皮!兄弟们耗子尾之!...

    文章末尾有python全套学习资料领取 1. python爬虫可以爬取大规模数据.Python具有丰富和强大的库.它常被昵称为胶水语言,能够把用其他语言制作的各种模块(尤其是C/C++)很轻松地联结在 ...

  5. 用于计算机视觉领域的python第三方库是什么_大量Python开源第三方库资源分类整理,含菜鸟教程章节级别链接...

    Python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明.因其具有丰富和强大的库,它常被称为胶水语言,能够把用其它语言制作的各种模块(尤其是C/C ...

  6. python操作excel_使用Python操作Excel时必学的3个库

    Python对Excel的操作我主要用xlwt.xlrd.xlutils这三个库. 1.xlwt主要用来创建并写入数据到Excel.已经存在的表不可以写入. 以下使用Python写九九乘法表到Exce ...

  7. python第三方库批量安装_使用Python批量安装第三方库

    Python的很多功能通过第三方库实现,99%的第三方库可以通过Python自带的pip方法进行自动下载和安装.然而Python有几十万个第三方库,最常用的也有几十个.想要一次性地安装几十个常用的第三 ...

  8. python的turtle怎么画曲线_利用 turtle库绘制简单图形

    turtle库是python的基础绘图库,这个库被介绍为一个最常用的用来介绍编程知识的方法库,其主要是用于程序设计入门,是标准库之一,利用turtle可以制作很多复杂的绘图. turtle名称含义为& ...

  9. python中turtle怎么确定坐标_关于Python turtle库使用时坐标的确定方法

    关于Python turtle库使用时坐标的确定方法 想画一个比较复杂的图像,而且还想用turtle画,最让人想退却的是无规律的笔势和繁多的坐标,但既然没有按奈住冲动的心,那我告诉你一个比较笨的方法吧 ...

最新文章

  1. My interested stuff(2008-07-10)
  2. 滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(11月9日~11月13日)...
  3. 从no-code到low-code:企业级hpaPaaS的未来
  4. ZendStudio-v6.0注册机
  5. centos6.5安装bugzilla超详细教程
  6. v-model数据绑定分析
  7. php mysql网页评论,PHP / MySQL:如何在您的网站中创建评论部分
  8. Scrapy操作浏览器获取网易新闻数据
  9. 在 Linux 的应用中测试中的延时和丢包模拟
  10. java数组函数_Java数组
  11. visio2013找到密钥以后但是未激活状态
  12. ISO 27001,能给企业带来哪些好处?
  13. pip install pyodbc : ERROR: Command errored out with exit status 1
  14. 漫画:头条面试官谈自我介绍
  15. matlab 2013至2016 32bit、64bit破解版集合 百度云盘下载
  16. 单核CPU处理多线程
  17. python模块-win32clipboard-访问windows剪切板-实现复制粘贴
  18. el-input输入字母转化大写字母
  19. Android 底层知识拾零,app架构升级
  20. 原画 机器人总动员_《机器人瓦力》导演执导 科幻史诗巨制《火星上的约翰·卡特》首支震撼预告...

热门文章

  1. Maven 新版本 3.8.1 打包报错 maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories
  2. Rocket 架构设计
  3. 一看就会的20个“非常有用”的python小技巧,你一定要试试
  4. JDK8 Stream操作 collectingAndThen:根据对象的属性去重
  5. grub2引导linux内核,一种基于grub2的linux系统启动bootloader的制作方法与流程
  6. python 可视化界面_工具推荐 | 3维数据可视化
  7. siesta在Linux运行,请教,为什么siesta编译中没报错,然而运行的时候跑不起来呢...
  8. java方法的调用怎么跳出_JAVA 的一个方法调用另一个方法时,怎么把那个方法里的数据调用出来...
  9. python下的橡皮线_python下载吴恩达deep learning编程习题
  10. jar java classpath_win7中java编程工具安装 java环境变量设置