控制行从Python编写yaml

时间:2018-01-10 01:22:40

标签: python yaml

我正在使用Python 3中的yaml库编写一个YAML文件,我想在编写一长串文本时选择换行符的位置。

这是我正在尝试做的事情的一个愚蠢的例子。 days条目是一个长文本块,其中几个项目以逗号分隔。我想把每个项目放在一条线上,但在这个例子中,“9 Ladies Dancing”会分开。

from yaml import safe_load, safe_dump

s = """\
- title: 12 Days of Christmas
- days: A partridge in a pear tree,
    2 Turtle Doves,
    3 French Hens,
    4 Calling Birds,
    5 Gold Rings,
    6 Geese a-Laying,
    7 Swans a-Swimming,
    8 Maids a-Milking,
    9 Ladies Dancing,
    10 Lords a-Leaping,
    11 Pipers Piping,
    12 Drummers Drumming
"""
l = safe_load(s)

print(safe_dump(l, default_flow_style=False))

打印出来:

- title: 12 Days of Christmas
- days: A partridge in a pear tree, 2 Turtle Doves, 3 French Hens, 4 Calling Birds,
    5 Gold Rings, 6 Geese a-Laying, 7 Swans a-Swimming, 8 Maids a-Milking, 9 Ladies
    Dancing, 10 Lords a-Leaping, 11 Pipers Piping, 12 Drummers Drumming

我想将days的全文加载为单行,但我想将其打印为多行,最多80个字符,以便更容易查看项目的正确性。我想在一行上有几个项目,但是我想用逗号分隔这些行,这样项目就不会在行之间分割。

2 个答案:

答案 0 :(得分:1)

一个简单的解决方案是将宽度设置为巨大的,但我不想这样做。

希望我还没有找到yaml库的一个功能,但这是我提出的最佳功能:

from yaml import safe_load, safe_dump, SafeDumper, dump

s = """\
- title: 12 Days of Christmas
- days: A partridge in a pear tree,
    2 Turtle Doves,
    3 French Hens,
    4 Calling Birds,
    5 Gold Rings,
    6 Geese a-Laying,
    7 Swans a-Swimming,
    8 Maids a-Milking,
    9 Ladies Dancing,
    10 Lords a-Leaping,
    11 Pipers Piping,
    12 Drummers Drumming
"""
l = safe_load(s)

print(safe_dump(l, default_flow_style=False))


class SplitDumper(SafeDumper):
    def write_plain(self, text, split=True):
        delimiter = ','
        if split:
            pieces = text.split(delimiter)
        else:
            pieces = [text]
        buffer = ''
        for i, piece in enumerate(pieces):
            if i > 0:
                buffer += delimiter
            if self.column-1 + len(buffer) + len(piece) <= self.best_width:
                buffer += piece
            else:
                super(SplitDumper, self).write_plain(buffer, split)
                self.write_indent()
                buffer = piece
        super(SplitDumper, self).write_plain(buffer)

print(dump(l, default_flow_style=False, Dumper=SplitDumper))

SplitDumper类会覆盖write_plain()方法,将其拆分为逗号中的块,然后检测每行可以写入的块数。

打印出默认拆分,然后是自定义拆分:

- title: 12 Days of Christmas
- days: A partridge in a pear tree, 2 Turtle Doves, 3 French Hens, 4 Calling Birds,
    5 Gold Rings, 6 Geese a-Laying, 7 Swans a-Swimming, 8 Maids a-Milking, 9 Ladies
    Dancing, 10 Lords a-Leaping, 11 Pipers Piping, 12 Drummers Drumming

- title: 12 Days of Christmas
- days: A partridge in a pear tree, 2 Turtle Doves, 3 French Hens, 4 Calling Birds,
     5 Gold Rings, 6 Geese a-Laying, 7 Swans a-Swimming, 8 Maids a-Milking,
     9 Ladies Dancing, 10 Lords a-Leaping, 11 Pipers Piping, 12 Drummers Drumming

答案 1 :(得分:1)

字符串在加载后已经是一行:

>>> l
[{'title': '12 Days of Christmas'}, {'days': 'A partridge in a pear tree, 2 Turtle Doves, 3 French Hens, 4 Calling Birds, 5 Gold Rings, 6 Geese a-Laying, 7 Swans a-Swimming, 8 Maids a-Milking, 9 Ladies Dancing, 10 Lords a-Leaping, 11 Pipers Piping, 12 Drummers Drumming'}]

您是否考虑使用过块?见Preserve new lines in YAML

>>> s = """\
... - title: 12 Days of Christmas
... - days: |-
...     A partridge in a pear tree,
...     2 Turtle Doves,
...     3 French Hens,
...     4 Calling Birds,
...     5 Gold Rings,
...     6 Geese a-Laying,
...     7 Swans a-Swimming,
...     8 Maids a-Milking,
...     9 Ladies Dancing,
...     10 Lords a-Leaping,
...     11 Pipers Piping,
...     12 Drummers Drumming
... """
>>> safe_load(s)
[{'title': '12 Days of Christmas'}, {'days': 'A partridge in a pear tree,\n2 Turtle Doves,\n3 French Hens,\n4 Calling Birds,\n5 Gold Rings,\n6 Geese a-Laying,\n7 Swans a-Swimming,\n8 Maids a-Milking,\n9 Ladies Dancing,\n10 Lords a-Leaping,\n11 Pipers Piping,\n12 Drummers Drumming'}]