--------------------------------------------------首先是dump的整体流程--------------------------------------------------------
ruamel.yaml首先需要setup一下component:
使用dump时的过程首先serializer.open后会发送一个StreamStartEvent,表示流开始
然后会有representer class首先解析给定的字典,入口源码如下:
open中的内容:
整体模式是多线程的订阅者模式,因此主线程这里只负责发送event,然后开始使用representer对数据进行表示。
以yaml.RoudTripRepresenter为例,它继承了SafeRepresenter,重写了一些方法,用于定义自己的表示模式:
在进行represent后,data会变成有tag的(k, v)模式,例如,这里可以打断点查看,并且这里的结构仍然与字典相同,是嵌套的node, 表示完后会由serializer将node作序列化,这是represent的一部分,源码如下:
主线程的工作主要是发送事件和表示数据,接下来由Emitter对数据进行处理,里面核心的数据结构是栈,点进来可以看到很多field,记录了各种标定值,如indent的长度,最佳宽度等
真正处理数据的function是expect_node, 它对于不同的Event会有各种不同的处理,是否增加当前深度,是否弹出当前stats,等等,这个function比较长,此处只截取部分:
大致流程就是这样
---------------------------------------------------接下来是如何自定义格式----------------------------------------------------------------
如果你认真阅读了上面的内容,应该大致明白了,我们需要修改的就是representer,用来自定义我们想要的数据表示格式。
以字符串为例,假如使用默认的RoundTripDumper,字符串会被前后加上引号,并且当中的换行等会被转义,像下面这样
那么,当我们仍然想使用RoundTripDumper(因为它可以保持OrderedDict的顺序),又希望string能以如下方式表示(以竖线|开头,保留原格式)的时候,就需要给RoundTripRepresenter中添加一个representer了
需要来定义一个str_representer function, 在当中定义style为'|'
然后将其加入:
完成
类似的,如果想折叠list结构,即使用flow style,就需要一个这样的function(这个function写在了某个class中,因此首个param是cls):