ruamel.yaml 的早期版本不会保留空行,但是通过在所有注释发出时通过的位置剥离换行符来恢复这种行为相对容易:Emitter.write_comment()
in ruamel/yaml/emitter.py
。幸运的是,由空格后跟换行符组成的行已经简化为换行符。本质上,不是在您的数据中搜索附加的评论并弄清楚如何重写它们,而是让评论来找您。
我包含了一些更多的空注释行案例来测试功能:
import sys
import ruamel.yaml
yaml_str = """\
---
a:
b: '1'
# comment followed by empty lines
c: "2"
d: 3
# Comment.
e: 4
# empty lines followed by comment
f: 5
# comment between empty lines
g: |+
an empty line within a multi-line literal
with a trailing empty line that is not stripped
h: 6
# final top level comment
"""
# rename the comment writer
ruamel.yaml.emitter.Emitter.write_comment_org = ruamel.yaml.emitter.Emitter.write_comment
# define your own comment writer that calls the orginal if the comment is not empty
def strip_empty_lines_write_comment(self, comment):
# print('{:02d} {:02d} {!r}'.format(self.column, comment.start_mark.column, comment.value))
comment.value = comment.value.replace('\n', '')
if comment.value:
self.write_comment_org(comment)
# install
ruamel.yaml.emitter.Emitter.write_comment = strip_empty_lines_write_comment
data = ruamel.yaml.round_trip_load(yaml_str, preserve_quotes=True)
ruamel.yaml.round_trip_dump(data, sys.stdout)
给出:
a:
b: '1'
# comment followed by empty lines
c: "2"
d: 3
# Comment.
e: 4
# empty lines followed by comment
f: 5
# comment between empty lines
g: |+
an empty line within a multi-line literal
with a trailing empty line that is not stripped
h: 6
# final top level comment
这当然会影响“安装”后的所有转储数据strip_empty_lines_write_comment
。如果您的程序还需要使用空行转储数据,那么您需要基于子类StrippingEmitter
并Emitter
使用该子类创建StrippingRoundTripDumper
(如RoundTripDumper
in ruamel/yaml/dumper.py
)。
(您当然可以从代码中删除注释掉的调试打印语句)